Как сказал @ Cat ++, BOOST_STRONG_TYPEDEF - хорошее решение. Однако для тех, кто не хочет полагаться на библиотеку наддува (не ошибайтесь, если вы это сделаете), проще сделать это следующим образом:
#define TYPEDEF(original_type,target_type)struct target_type{\
original_type value;\
explicit target_type(const original_type val):value(val){}\
target_type(){}\
target_type(const target_type& other):value(other.value){}\
target_type& operator=(const original_type& rhs){value = rhs; return *this;}\
target_type& operator=(const target_type& rhs){value = rhs.value; return *this;}\
bool operator==(const target_type& rhs){return value == rhs.value;}\
bool operator<(const target_type& rhs){return value < rhs.value;}\
operator const original_type&() const{return value;}\
operator original_type&(){return value;}\
}
Использование: TYPEDEF(int, MyType);
Так что же делает этот макрос?
Этот макрос в основном создает новую структуру, которую можно легко трактовать как исходный тип разными способами. А для компилятора это совершенно другой тип.
Возьмите, к примеру, MyType
. Когда вы объявляете его как typedef int MyType;
, во время компиляции MyType
заменяется на int
. А поскольку у вас уже есть функция, определенная с int
в качестве параметра, она будет жаловаться на дублирование тела функции.
Когда вы делаете TYPEDEF(int, MyType);
, MyType - это структура, которая может быть инициализирована и ей присвоено значение типа int, и компилятор будет рассматривать ее как совершенно другой тип данных от int. Тем не менее, вы сможете назначить ему int
значения из-за функции operator =
и получить его значение как int
из-за его функций operator const original_type&() const
и operator original_type&()
.
Это примерно то, что boost делает со своим макросом BOOST_STRONG_TYPEDEF
, но, похоже, он наследуется от других внутренних классов, и я не уверен, что эти классы делают. Но это грубое решение для тех, кто не хочет полагаться на повышение по любой причине.
Моя личная рекомендация : Используйте буст по возможности.