Вывод различных и несравнимых типов из int в С++
Я знаю, что я не могу извлечь из int, и это даже не нужно, это было просто одно (не) решение, которое пришло мне в голову для проблемы ниже.
У меня есть пара (foo,bar)
, каждая из которых представлена внутри int
, но я хочу, чтобы typeof(foo)
был несравнимым с typeof(bar)
. Это, главным образом, не позволяет мне передать (foo,bar)
функции, ожидающей (bar, foo)
. Если я правильно ее понимаю, typedef
не сделает этого, поскольку это только псевдоним. Каким будет самый простой способ сделать это. Если бы я создал два разных класса для foo
и bar
, было бы утомительно явно предоставить все операторы, поддерживаемые int
. Я хочу этого избежать.
Ответы
Ответ 1
В качестве альтернативы написанию этого файла вы можете использовать макрос BOOST_STRONG_TYPEDEF
, доступный в заголовке boost/strong_typedef.hpp
.
// macro used to implement a strong typedef. strong typedef
// guarentees that two types are distinguised even though the
// share the same underlying implementation. typedef does not create
// a new type. BOOST_STRONG_TYPEDEF(T, D) creates a new type named D
// that operates as a type T.
Так, например,
BOOST_STRONG_TYPEDEF(int, foo)
BOOST_STRONG_TYPEDEF(int, bar)
Ответ 2
template <class Tag>
class Int
{
int i;
public:
Int(int i):i(i){} //implicit conversion from int
int value() const {return i;}
operator int() const {return i;} //implicit convertion to int
};
class foo_tag{};
class bar_tag{};
typedef Int<foo_tag> Foo;
typedef Int<bar_tag> Bar;
void f(Foo x, Bar y) {...}
int main()
{
Foo x = 4;
Bar y = 10;
f(x, y); // OK
f(y, x); // Error
}
Ответ 3
Вы правы, что вы не можете сделать это с помощью typedef
. Однако вы можете обернуть их в пару struct-enum
или int
, заключенную внутри struct
.
template<int N>
struct StrongType { // pseudo code
int i;
StrongType () {}
StrongType (const int i_) : i(i_) {}
operator int& () { return i; }
StrongType& operator = (const int i_) {
i = i_;
return *this;
}
//...
};
typedef StrongType<1> foo;
typedef StrontType<2> bar;
Решение С++ 0x:
enum class foo {};
enum class bar {};