Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.04.2013, 10:05   #1
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию Обвертка для встроенных типов

Есть ли такой механизм:
Код:
typedef int t_1;
typedef int t_2;
void fn(t_1) {}
int main()
{
   t_1 ti_1;
   t_2 ti_2;
   fn(ti_1);	// ok
   fn(ti_2);	// error
   return 0;
}
Понимаю, что typedef не годится. Знаю что можно создать класс и перегрузить операторы, но это хлопотно. Может есть какая-то штучка (возможно како-то базовый класс) в std для реализации затеи?
220Volt вне форума Ответить с цитированием
Старый 03.04.2013, 10:30   #2
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Оно?
В предложенном решении, правда, используется не STL, а Boost. С другой стороны, если Вы им ещё не пользуетесь, стоит срочно начать.
Abstraction вне форума Ответить с цитированием
Старый 03.04.2013, 10:38   #3
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

Похоже оно, спасибо, буду разбираться.

Честно говоря, надеялся, что и это будет запрещено:
Код:
#include <boost\serialization\strong_typedef.hpp>
BOOST_STRONG_TYPEDEF(int, i1)
BOOST_STRONG_TYPEDEF(int, i2)

int main()
{
	i1 val1;
	i2 val2;
	val1 = val2; // ok
}
Т.е. отсутствие operator=(base_type), только explicit конструктор. Иначе говоря перегрузка всех операторов, а не приведение к базовому типу.

Последний раз редактировалось Stilet; 04.04.2013 в 12:14.
220Volt вне форума Ответить с цитированием
Старый 03.04.2013, 20:50   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Ну так сделайте сами - там макрос на 10 строчек...
waleri вне форума Ответить с цитированием
Старый 04.04.2013, 03:37   #5
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Ну так сделайте сами - там макрос на 10 строчек...
У меня получилось около 140 )) (перегрузка операторов.)

Цитата:
Сообщение от 220Volt Посмотреть сообщение
Честно говоря, надеялся, что и это будет запрещено:
Код:
#include <boost\serialization\strong_typedef.hpp>
BOOST_STRONG_TYPEDEF(int, i1)
BOOST_STRONG_TYPEDEF(int, i2)

int main()
{
	i1 val1;
	i2 val2;
	val1 = val2; // ok
}
Т.е. отсутствие operator=(base_type), только explicit конструктор. Иначе говоря перегрузка всех операторов, а не приведение к базовому типу.
Хотя, наверное, в таком случаи нарушится работа каких-нибудь библиотек. Видимо функциональность большая чем BOOST:strong_typedef не нужна.

Последний раз редактировалось Stilet; 04.04.2013 в 12:16.
220Volt вне форума Ответить с цитированием
Старый 04.04.2013, 09:06   #6
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Цитата:
Сообщение от 220Volt Посмотреть сообщение
У меня получилось около 140 )) (перегрузка операторов.)
Тогда сделайте класс-шаблон а макрос будет делать класс-наследник этого шаблона... Кроме того, если класс имеет operator type&() тогда операторы не надо перегружать.
waleri вне форума Ответить с цитированием
Старый 04.04.2013, 09:31   #7
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

Это по сути и есть typedef из boosta, я уже определился, использую вышеназванную библиотеку, не хочу заново велосипед делать.
220Volt вне форума Ответить с цитированием
Старый 04.04.2013, 11:45   #8
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Ну, вы же жаловались, что что-то там не так, как вам надо... если их велосипед вас устраивает...
waleri вне форума Ответить с цитированием
Старый 04.04.2013, 12:40   #9
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Ну, вы же жаловались, что что-то там не так, как вам надо... если их велосипед вас устраивает...
Как реализовать я знаю, даже сделал, но слишком много творчества в таком варианте и подозреваю, что возможны конфликты с библиотеками.
Если интересно, вот что получилось + демонстрация поведения (особо не тестил, возможны ошибки):
Код:
template <typename _Ty, typename _Val>
	class Base_type_wrap
	{
		_Val value;
	public:
		explicit Base_type_wrap(_Val value): value(value) {}
		Base_type_wrap(void) {}
		~Base_type_wrap(void) {}
		operator _Val&()	{ return this->value; }
		operator const _Val&()const	{ return this->value; }
		_Ty &operator++()	{ ++this->value; return *(_Ty*)this; }
		_Ty &operator--()	{ --this->value; return *(_Ty*)this; }
		_Ty operator++(int)	
		{
			_Ty ret(*this);
			++this->value; 
			return ret;
		}
		_Ty operator--(int)	
		{
			_Ty ret(*this);
			--this->value; 
			return ret;
		}
		_Ty operator-()
		{
			_Ty ret(*this);
			ret.value = -ret.value;
			return ret;
		}
		_Ty operator+()
		{
			_Ty ret(*this);
			ret.value = +ret.value;
			return ret;
		}
		_Ty operator!()
		{
			_Ty ret(*this);
			ret.value = !ret.value;
			return ret;
		}
		_Ty operator~()
		{
			_Ty ret(*this);
			ret.value = ~ret.value;
			return ret;
		}
		_Ty operator*(const _Ty &out)
		{
			_Ty ret(*this);
			ret.value *= out.value;
			return ret;
		}
		_Ty operator/(const _Ty &out)
		{
			_Ty ret(*this);
			ret.value /= out.value;
			return ret;
		}
		_Ty operator%(const _Ty &out)
		{
			_Ty ret(*this);
			ret.value %= out.value;
			return ret;
		}
		_Ty operator+(const _Ty &out)
		{
			_Ty ret(*this);
			ret.value += out.value;
			return ret;
		}
		_Ty operator<<(int shift)
		{
			_Ty ret(*this);
			ret.value = ret.value<<shift;
			return ret;
		}
		_Ty operator>>(int shift)
		{
			_Ty ret(*this);
			ret.value = ret.value>>shift;
			return ret;
		}
		bool operator<(const _Ty &out)	{ return(this->value < out.value); }
		bool operator<=(const _Ty &out)	{ return(this->value <= out.value); }
		bool operator>(const _Ty &out)	{ return(this->value > out.value); }
		bool operator>=(const _Ty &out)	{ return(this->value >= out.value); }
		bool operator==(const _Ty &out)	{ return(this->value == out.value); }
		bool operator!=(const _Ty &out)	{ return(this->value != out.value); }
		_Ty operator&(const _Ty &out) 
		{
			_Ty ret(*this);
			ret.value &= out.value;
			return ret;
		}
		_Ty operator^(const _Ty &out)
		{
			_Ty ret(*this);
			ret.value ^= out.value;
			return ret;
		}
		_Ty operator|(const _Ty &out)
		{
			_Ty ret(*this);
			ret.value |= out.value;
			return ret;
		}
		bool operator&&(const _Ty &out)	{ return(this->value && out.value); }
		bool operator||(const _Ty &out)	{ return(this->value || out.value); }
		_Ty &operator+=(const _Ty &out) { this->value += out.value; return *(_Ty*)this; }
		_Ty &operator-=(const _Ty &out) { this->value -= out.value; return *(_Ty*)this; }
		_Ty &operator*=(const _Ty &out) { this->value *= out.value; return *(_Ty*)this; }
		_Ty &operator/=(const _Ty &out) { this->value /= out.value; return *(_Ty*)this; }
		_Ty &operator%=(const _Ty &out) { this->value %= out.value; return *(_Ty*)this; }
		_Ty &operator<<=(int shift) { this->value <<= shift; return *(_Ty*)this; }
		_Ty &operator>>=(int shift) { this->value >>= shift; return *(_Ty*)this; }
		_Ty &operator&=(const _Ty &out) { this->value %= out.value; return *(_Ty*); }
		_Ty &operator^=(const _Ty &out) { this->value ^= out.value; return *(_Ty*)this; }
		_Ty &operator|=(const _Ty &out) { this->value |= out.value; return *(_Ty*)this; }
	};

#define MY_TYPEDEF(base_type, name)										\
	class name : public Base_type_wrap<name, base_type>					\
	{																	\
	public:																\
		name(void) {}													\
		explicit name(base_type value): Base_type_wrap(value) {}		\
	};

	MY_TYPEDEF(int, type_1)
	MY_TYPEDEF(int, type_2)

	void fn(type_1 &) {}
        void fn2(int &) {}

int main()
{
	type_1 t1(4), t11;
	type_2 t2(2), t22;
	t2 ++;				// ok
	t22 = t2 ++;		// ok
	t22 = -- t2;		// ok
	t11 = t1 <<= 3;		// ok
	fn(t1);				// ok
	fn(t2);				// error
	t1 = t2;			// error          boost::strong_typedef так не может
        t1 = type_1(t2);	        // ok
	fn2(t2);			// ok

	return 0;
}

Последний раз редактировалось 220Volt; 04.04.2013 в 13:43.
220Volt вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
HTTP сервер для встроенных систем ReRayne C/C++ Сетевое программирование 0 18.01.2012 00:30
Требуется программист для встроенных систем г. Минск indelagroup Фриланс 0 14.01.2011 16:01
C++ для встроенных систем управления. p_embeder Общие вопросы C/C++ 1 28.11.2008 19:28