在C ++ 11中,是否有一种干净的方法来禁用typedef之间的隐式转换,或者你是否需要做一些令人讨厌的事情,比如在类中包装int并定义和删除各种运算符?
typedef int Foo;
typedef int Bar;
Foo foo(1);
Bar bar(2);
bar = foo; // Implicit conversion!
在C ++ 11中,是否有一种干净的方法来禁用typedef之间的隐式转换,或者你是否需要做一些令人讨厌的事情,比如在类中包装int并定义和删除各种运算符?
typedef int Foo;
typedef int Bar;
Foo foo(1);
Bar bar(2);
bar = foo; // Implicit conversion!
你好,世界 解释为什么你有什么不能工作。你需要通常被称为“强大”的东西 typedef
做你想做的事。一个示例实现是 BOOST_STRONG_TYPEDEF
:
#include <boost/serialization/strong_typedef.hpp>
BOOST_STRONG_TYPEDEF(int, a)
void f(int x); // (1) function to handle simple integers
void f(a x); // (2) special function to handle integers of type a
int main(){
int x = 1;
a y;
y = x; // other operations permitted as a is converted as necessary
f(x); // chooses (1)
f(y); // chooses (2)
}
如果我们做了 typedef int a;
那么代码就会模糊不清。
C ++标准说:
7.1.3 typedef说明符
使用typedef说明符声明的名称将成为typedef-name。在其声明的范围内,typedef-name是 语法上等同于关键字,并命名与标识符关联的类型 在 第8章中描述的方式.typedef-name是 因此是另一种类型的同义词。一个typedef-name可以 不要以类声明的方式引入新类型 (9.1)或枚举声明
但是例如 class
要么 struct
介绍新类型。在以下示例中 uniqueUnused
实际上什么都没有,但用于创建一个不同的类型 Value<int, 1> != Value<int, 2>
。所以也许这是你正在寻找的东西。 请记住,无法保证编译器摆脱外部结构!这个代码唯一的保证是它与int的大小相同
template<typename T, int uniqueUnused>
struct Value
{
Value() : _val({}) {}
Value(T val) : _val(val) { }
T _val;
operator T&() { return _val; }
// evaluate if you with or without refs for assignments
operator T() { return _val; }
};
using Foo = Value<int, 1>;
using Bar = Value<int, 2>;
static_assert(sizeof(Foo) == sizeof(int), "int must be of same size");
static_assert(sizeof(Bar) == sizeof(int), "int must be of same size");
如果你想基于一个类创建一个新类型,你可以简单地使用这个例子(这不适用于标量类型,因为你不能从int继承):
class Foo : public Bar // introduces a new type called Foo
{
using Bar::Bar;
};
这不是严格的类型检查,但可以进行非法转换 可见 通过使用原始,或 应用匈牙利表示法 (H.N.)。如果你认为H. N.意味着名字类型为前缀,那你就错了(就是这样 系统H. N.,它是,嗯,不必要的命名开销)。
使用(Apps)H.N。,变量前缀标记不是类型(例如, INT),但目的,例如,计数器,长度,秒等。因此,当您向变量添加计数器包含已用时间时,您可以编写 cntSomethingCounter + secElapsedSinceLastSomething
,你可以看到它闻起来。编译器不会发出警报,但它会引起你的注意。