我可以将隐式初始化重载为 0 吗?
Posted
技术标签:
【中文标题】我可以将隐式初始化重载为 0 吗?【英文标题】:Can I overload an implicit initialization to 0? 【发布时间】:2013-06-17 12:17:50 【问题描述】:是否可以编写一个使这些有效的类:
Foo a;
Foo b = 0;
Foo c = b;
Foo d(0);
Foo e(1);
Foo f = Foo(1);
但这些不是:
int x;
Foo a = x;
Foo b = 1;
Foo c = 2;
//etc
基本上,我的规则是“常量0
可以隐式转换为Foo
,但没有其他值”
【问题讨论】:
Foo e(1);
呢?这怎么有效?
@LuchianGrigore:它们在语义上是否相同?如果是这样,我想我可以宣布无效。
也许您可以尝试使用带有std::nullptr_t
的构造函数(只是一个想法......)
如果x
是const int x = 0;
,你希望a
的初始化成功吗?
也许这可能有用:***.com/questions/3299834/…***.com/questions/7658060/…
【参考方案1】:
Foo e(1);
将调用 Foo 的非显式构造函数,以 int 作为参数。 本质上,这一行将通过尝试使用此 int 构造函数将 int 转换为 Foo 来做同样的事情。
Foo b = 1;
您不能阻止直接处理该 int 的某些值。
如果你有你的构造函数explicit
,你也不能写下一行。
Foo b = 0;
gx_ 正确地指出 0 可以转换为 std::nullptr_t。 以下内容将根据您的意图起作用。
Foo(std::nullptr_t x) : member(0)
explicit Foo(int c) : member(c)
// ...
Foo a = 0; // compiles
Foo b = 1; // doesn't compile
// Note:
int do_stuff (void) return 0;
Foo c = do_stuff(); // doesn't compile
【讨论】:
不,直接与复制初始化。 一个explicit Foo(int);
加上一个Foo(nullptr_t);
怎么样?【参考方案2】:
我的一个想法是:
Foo(const uint32_t c) : member(0) static_assert(c == 0, "Nope");
explicit Foo(uint32_t c) : member(c)
这样做是否合理?
【讨论】:
那甚至无法编译。就重载解析而言,const uint32_t
参数和uint32_t
参数是一回事。【参考方案3】:
如果您不介意 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;
;
我还没有真正尝试过这个。理论上,模板应该只在参数为nullptr
时参与重载决议,否则 SFINAE 会杀死它。但是,在这种情况下,它应该比指针构造函数更好。
【讨论】:
【参考方案4】:我承认我还没有完全掌握 C++11 的右值语义,但这似乎是你想要的:
class Foo
public:
Foo(int&&)
;
int main()
Foo a(123);
int x = 123;
Foo b(x); // error here, line 11
return 0;
结果:
prog.cpp:11: 错误:无法将‘int’左值绑定到‘int&&’
欢迎评论,如果此代码有任何我没有注意到的警告,或者您可以向我保证它没有。
【讨论】:
有趣,但我的目标是x == 0
的具体案例;
@eric 啊,没有意识到这一点。你说Foo e(1);
应该是有效的:/以上是关于我可以将隐式初始化重载为 0 吗?的主要内容,如果未能解决你的问题,请参考以下文章