使用整数常量0初始化实例,但没有其他常量值或整数变量

时间:2012-03-13 20:06:15

标签: c++

我想定义一个类,其实例可以构造,隐式构造,或者从整数常量零赋值,但不能从任何其他数值常量赋值,而不能从具有整数类型的变量(即使其值恰好是在运行时为零)。它也应该是同一类的其他实例的可复制构造。只要g ++ 4.6和MSVC 2010支持(在适当的模式下),就可以使用C ++ 11功能。

具体而言,给定

class X { /* ... */ };
void fn(X);

这些都应编译:

X a(0);
X b = 0;
X c; c = 0;
X d = a;
X e; e = a;
fn(0);

但这些不应该:

X f(1);
X g = 1;
X h; h = 1;
fn(1);

int ii = 23;
X a(ii);
X j = ii;
X k; k = ii;
fn(ii);

我尝试了这个,但它不起作用:

class X {
public:
   X() {} 
   constexpr X(int v) { static_assert(v == 0, "must be initialized from zero"); }
};

test.cc: In constructor ‘constexpr X::X(int)’:
test.cc:3:29: error: non-constant condition for static assertion
test.cc:3:29: error: ‘v’ is not a constant expression

3 个答案:

答案 0 :(得分:2)

如果需要C ++ 0x,您可以使用std::nullptr_t

class X
{
public:
  X () { }
  X (std::nullptr_t) { }
  void operator= (std::nullptr_t) { }
};

嗯,当然,X也可以通过nullptr进行初始化。

答案 1 :(得分:1)

您需要使用常量表达式替换(v == 0)...

这样的东西
constexpr bool is_zero_construct(size_t number)
{
  return number == 0;
}

constexpr X(int v) { static_assert(is_zero_construct(v), "must be initialized from zero"); }

答案 2 :(得分:0)

您可以利用只有0可以隐式转换为指针的事实:

struct X {
  X();
  X(void*);
};

这符合您的要求,但当然也允许使用指针进行初始化。