C++ 从C+中的int派生不同的和不可比较的类型+;
我知道我不能从int派生,它甚至没有必要,这只是我想到的下面这个问题的一个(非)解决方案C++ 从C+中的int派生不同的和不可比较的类型+;,c++,typechecking,C++,Typechecking,我知道我不能从int派生,它甚至没有必要,这只是我想到的下面这个问题的一个(非)解决方案 我有一对(foo,bar)它们都在内部由int表示,但我希望typeof(foo)与typeof(bar)不可比。这主要是为了防止我将(foo,bar)传递给需要(bar,foo)的函数。如果我理解正确,typedef将不会执行此操作,因为它只是一个别名。最简单的方法是什么。如果我要为foo和bar创建两个不同的类,那么显式地提供int支持的所有操作符将是一件乏味的事情。我想避免这种情况。你是对的,你不能用
我有一对
(foo,bar)
它们都在内部由int
表示,但我希望typeof(foo)
与typeof(bar)
不可比。这主要是为了防止我将(foo,bar)
传递给需要(bar,foo)
的函数。如果我理解正确,typedef
将不会执行此操作,因为它只是一个别名。最简单的方法是什么。如果我要为foo
和bar
创建两个不同的类,那么显式地提供int
支持的所有操作符将是一件乏味的事情。我想避免这种情况。你是对的,你不能用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;
模板
类Int
{
int i;
公众:
Int(inti):i(i){}//Int的隐式转换
int value()常量{return i;}
运算符int()常量{return i;}//到int的隐式转换
};
类foo_标记{};
类bar_标记{};
typedef Int-Foo;
输入条;
void f(Foo x,Bar y){…}
int main()
{
foox=4;
巴y=10;
f(x,y);//好的
f(y,x);//错误
}
除了自己编写之外,还可以使用header中提供的BOOST\u STRONG\u TYPEDEF
宏
所以,例如
BOOST_STRONG_TYPEDEF(int, foo)
BOOST_STRONG_TYPEDEF(int, bar)
您真的需要可以在int上执行的所有操作吗?隐藏一些甚至可能是一种优势@我要处理的是本质上不同的int子集。是的,所有操作都没有意义,例如
%
。但只想把乏味的东西保存下来,这取决于什么是foo
和bar
is。例如,使用定义的operator+
和operator-
创建类会增加抽象。这取决于您想要或需要的抽象程度。:-)或者使用BOOST\u STRONG\u TYPEDEF
()。@Armen:相反,您可以编写TYPEDEF intfoo;输入条代码>如果类模板参数不是类型,而是整数值。例如模板类Int{}
如果采用这种方法,则不需要xyz_标记
定义。@Cat Plus:它可以保证自己的答案:)@san:Sure:@san,@Armen:这是一个转换运算符,允许在必要时将类型转换为int
。不幸的是,正如Bo Persson所指出的,这是一个坏主意,因为你可以做foox;条形y=x+4
。。。转换回基础类型应该是显式的。你能告诉我一些我可以阅读的东西来理解这段代码吗。我对C++@iammilind不熟悉:注意C++0x对enum
有一些严格的要求。值得注意的是,假设foo
的最小值是min-value
,而foo
的最大值是max-value
,那么分配[min-value,max-value]
之外的任何内容都是未定义的行为。@san,我刚刚给出了区分类型的基本框架。您必须提供operator int()
,operator=()
等,才能有效地将foo
用作int
。让我试着编辑我的答案。@Cat Plus这似乎是最低限度的手指打字解决方案,谢谢。我没想到我的问题会产生这么多积极的答案和兴趣。不知所措。有趣的是,我注意到,BOOST\u STRONG\u TYPEDEF
采用了隐式转换运算符和显式构造函数的方法(这是合理的)。我从答案中学到了很多,现在我发现很难选择一个来接受。这是我将使用的一个,但是@armen和Iamilind的回答让我理解了封面下发生的事情,所以谢谢大家。接受这一点来分享战利品。
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
}
// 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)