在C ++中从int派生不同的和无法比较的类型

时间:2022-04-26 16:22:43

I know I cannot derive from an int and it is not even necessary, that was just one (non)solution that came to my mind for the problem below.

我知道我无法从一个int派生而且甚至没有必要,这只是我想到的下面问题的一个(非)解决方案。

I have a pair (foo,bar) both of which are represented internally by an int but I want the typeof(foo) to be incomparable with the typeof(bar). This is mainly to prevent me from passing (foo,bar) to a function that expects (bar, foo). If I understand it correctly, typedef will not do this as it is only an alias. What would be the easiest way to do this. If I were to create two different classes for foo and bar it would be tedious to explicitly provide all the operators supported by int. I want to avoid that.

我有一对(foo,bar),两者都由int内部表示,但我希望typeof(foo)与typeof(bar)无法比较。这主要是为了防止我将(foo,bar)传递给期望的函数(bar,foo)。如果我理解正确,typedef将不会这样做,因为它只是一个别名。最简单的方法是什么?如果我要为foo和bar创建两个不同的类,那么显式提供int支持的所有运算符将会非常繁琐。我想避免这种情况。

3 个解决方案

#1


18  

As an alternative to writing it yourself, you can use BOOST_STRONG_TYPEDEF macro available in boost/strong_typedef.hpp header.

作为自己编写的替代方法,您可以在boost / strong_typedef.hpp标头中使用BOOST_STRONG_TYPEDEF宏。

// 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.

So, e.g.

BOOST_STRONG_TYPEDEF(int, foo)
BOOST_STRONG_TYPEDEF(int, bar)

#2


10  

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


1  

You are correct, that you cannot do it with typedef. However, you can wrap them in a struct-enum pair or int encapsuled inside struct.

你是对的,你不能用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;

C++0x solution:

enum class foo {};
enum class bar {};

#1


18  

As an alternative to writing it yourself, you can use BOOST_STRONG_TYPEDEF macro available in boost/strong_typedef.hpp header.

作为自己编写的替代方法,您可以在boost / strong_typedef.hpp标头中使用BOOST_STRONG_TYPEDEF宏。

// 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.

So, e.g.

BOOST_STRONG_TYPEDEF(int, foo)
BOOST_STRONG_TYPEDEF(int, bar)

#2


10  

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


1  

You are correct, that you cannot do it with typedef. However, you can wrap them in a struct-enum pair or int encapsuled inside struct.

你是对的,你不能用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;

C++0x solution:

enum class foo {};
enum class bar {};