C ++: перегрузка операторов для похожих целочисленных типов - PullRequest
2 голосов
/ 21 февраля 2012

У меня есть тип с именем MyType, который является int:

typedef int MyType;

. В коде он обрабатывается как int.

Я бы хотелбыть в состоянии перегрузить оператора отдельно для int и MyType:

class C
{
public:
   C& operator>>(int i) {}
   C& operator>>(MyType i) {}
};

, но я не могу:

overload.cpp:7:7: error: 'C& C::operator>>(MyType)' cannot be overloaded
overload.cpp:6:7: error: with 'C& C::operator>>(int)'

Могу ли я взять свой пирог и съесть его тоже

Ответы [ 2 ]

6 голосов
/ 21 февраля 2012

Как обычно, вам нужен сильный typedef. Одна реализация этого является BOOST_STRONG_TYPEDEF.

4 голосов
/ 21 февраля 2012

Как сказал @ 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, но, похоже, он наследуется от других внутренних классов, и я не уверен, что эти классы делают. Но это грубое решение для тех, кто не хочет полагаться на повышение по любой причине.

Моя личная рекомендация : Используйте буст по возможности.

...