С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
rs4i
1 / 1 / 0
Регистрация: 25.06.2009
Сообщений: 13
#1

Реализация идеомы UniqueType - C++

25.06.2009, 22:12. Просмотров 698. Ответов 5
Метки нет (Все метки)

Идея проста и стоит во главе идеологии C++:
C++
1
2
std::string password, login;
unsigned short TCPport, YearOfBirth;
Компилятор запрещает бессмысленные присвоения:
C++
1
login = TCPport; // error
Однако не менее бессмысленные:
C++
1
password = login; TCPport = YearOfBirth; // ok
запретить не может.
Писать класс для каждого подобного типа не реально.
Возникла идея написать шаблон прокси класса:
C++
1
2
3
4
5
6
7
template< class ContainType >class UniqueType{
  ContainType value;
public:
  UniqueType( ContainType value ): value( value ){}
  operator ContainType(){ return value; }
  // При необходимости перегружаем еще что-нибудь.
};
Вопрос как обеспечить уникальность типа.
Очевидное решение слегка не удобно:
C++
1
2
3
template< class ContainType, class Name >class UniqueType;
struct myPasword{}; // каждый раз определять новые бесполезные именные типы
UniqueType< std::string, myPasword > password; // уникальный тип
Пытался сделать так:
C++
1
2
3
template< class ContainType, int n >class UniqueType;
UniqueType< std::string, 1 > password; // уникальный тип
UniqueType< std::string, 2 > login; // уникальный тип
только вместо чисел подставить некий шаблон счетчик,
однако реализовать его не смог Мозг ушел в глубокую рекурсию
Бегло просмотрев кое-что по лиспу, стал подозревать что это не возможно.
Остались вопросы:
1. Как реализовать шаблон UniqueType?
2. Можно ли здесь обойтись без макросов?
3. Возможно ли в принципе реализовать шаблон счетчик или иной генератор?
4. Кто-нибудь где-нибудь встречался с подобной идеомой?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Vourhey
Почетный модератор
6486 / 2260 / 123
Регистрация: 29.07.2006
Сообщений: 12,536
27.06.2009, 18:53 #2
Скажи, что бессмысленного в присвоениии значения одной переменой другой?
Компилятор вполне осмысленно запрещает тебе присвоение значения одного типа переменной совершенно иного. Это предупреждает неопределенность в поведении программы и обращает внимание программиста на то, что он нифига не указал, че сделать хочет.
То, что хочешь сделать ты, я тоже слабо понимаю.
0
Evg
Эксперт CАвтор FAQ
18377 / 6424 / 441
Регистрация: 30.03.2009
Сообщений: 17,838
Записей в блоге: 28
27.06.2009, 19:03 #3
Из-за проблем с форумом часть постов похерилась. В общем, ему нужны типы, которые логически бы означали разные вещи. Что-то типа "typedef int aaa_t; typedef int bbb_t;" но при этом чтобы переменную типа aaa_t (которая, например означает килограммы), нельзя было присвоить в перменную типа bbb_t (которая означает километры).

rs4i, кроме черезж$пного способа, до которого ты уже и сам додумался (шаблон от двух типов, один из которых фиктивный, но уникальный), вроде бы больше ниикак не сделать
0
rs4i
1 / 1 / 0
Регистрация: 25.06.2009
Сообщений: 13
29.06.2009, 08:04  [ТС] #4
Найден вот такой подход:
template< class T, int > class UniqueType{ /**/ };
UniqueType< std::string, __LINE__ > login = "rs4i";
UniqueType< std::string, __LINE__ > pass = "******";
login = pass; // error
Все это легко оборачиваеться в макрос.
Выглядеть будет приблизительно так:
MacroUniqueType( std::string ) login = "rs4i";
Это не совсем коректно, так как, в разных файлах на одинаковый по номеру строках можно создать одинаковые типы.

Добавлено через 28 минут 25 секунд
еще тему нарыл:
http://rsdn.ru/forum/cpp/2337981.aspx
0
Evg
Эксперт CАвтор FAQ
18377 / 6424 / 441
Регистрация: 30.03.2009
Сообщений: 17,838
Записей в блоге: 28
29.06.2009, 10:03 #5
Ты уверен, что такой многоэтажный геморрой стОит того, чтобы с ним связываться?
0
rs4i
1 / 1 / 0
Регистрация: 25.06.2009
Сообщений: 13
29.06.2009, 12:36  [ТС] #6
Цитата Сообщение от Evg Посмотреть сообщение
Ты уверен, что такой многоэтажный геморрой стОит того, чтобы с ним связываться?
Не уверен. Более того, думаю что не стоит.
Код счетчика
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
 
static const int max = 498;
char engine( ... );
template< int I >struct number: public number< I - 1 >{};
template<>struct number< 0 >{};
template< int id = sizeof( engine( number< max >() ) ) >struct counter{
    friend char( &engine( number< id + 1 > ) )[ id + 1 ];
    static const int val = id - 1;
};
 
int main(){
    std::cout << counter<>::val << std::endl; // 0
    std::cout << counter<>::val << std::endl; // 1
    std::cout << counter<>::val << std::endl; // 2
    return 0;
}
Под VС9 больше 498 не считает, а под GCC не работает.
Решение конечно интересное .. но .. похоже бесполезное.
Еще не вечер. Может нарою еще что.
0
29.06.2009, 12:36
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.