我可以将隐式初始化重载为0吗?

Eri*_*ric 8 c++ constructor initializer explicit-constructor

是否可以编写一个类,使其有效:

Foo a;
Foo b = 0;
Foo c = b;
Foo d(0);
Foo e(1);
Foo f = Foo(1);
Run Code Online (Sandbox Code Playgroud)

但这些不是:

int x;
Foo a = x;
Foo b = 1;
Foo c = 2;
//etc
Run Code Online (Sandbox Code Playgroud)

从本质上讲,我的规则是"一个常量0可以隐式转换为a Foo,但没有其他值"

Seb*_*edl 5

如果你不介意Foo b = nullptr;工作,那很容易被破解.有一个显式的构造函数int,一个隐式的std::nullptr_t.

如果你介意工作,我不确定它是否可行.区分文字0和其他整数文字的唯一方法是前者对指针的隐式转换nullptr_t.因此,nullptr更喜欢nullptr_t参数指针参数,因此通过使用两个构造函数,您可以过滤掉nullptr参数.但是,0对指针的转换具有nullptr_t相同的等级,所以这会0以含糊不清的方式杀死参数.

嗯......这样的事情可能有用:

class Foo {
  struct dummy;
public:
  explicit Foo(int); // the version that allows Foo x(1);
  Foo(dummy*); // the version that allows Foo x = 0;
  template <typename T,
            typename = typename std::enable_if<
                std::is_same<T, std::nullptr_t>::value>::type>
  Foo(T) = delete; // the version that prevents Foo x = nullptr;
};
Run Code Online (Sandbox Code Playgroud)

我还没试过这个.理论上,模板应该只在参数出现时参与重载解析nullptr,因为否则SFINAE会将其杀死.但是,在这种情况下,它应该比指针构造函数更好.