我可以将隐式初始化重载为 0 吗?
Can I overload an implicit initialization to 0?
是否可以编写一个类,使这些类有效:
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 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会杀死它。但是,在这种情况下,它应该比指针构造函数更好。
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
我的一个想法是:
Foo(const uint32_t c) : member(0) { static_assert(c == 0, "Nope"); }
explicit Foo(uint32_t c) : member(c) { }
这是否合理?
我承认我还没有完全掌握 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&&">
欢迎评论,如果这段代码有任何我没有注意到的警告,或者你可以向我保证它没有。
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 为什么初始化时没有调用重载赋值运算符?
- 通过 C++ 中的重载构造函数初始化未知类型的变量
- 模板流运算符重载错误:引用初始化无效,与basic_istream和basic_ifstream之间的差异有关
- C++ 重载和覆盖 - 无法使用类型的右值初始化类型的参数
- 重载右值和左值引用的工厂函数 - 高效初始化
- 为什么我的重载运算符+在向自身添加变量时会在返回时使"this"未初始化?
- 重载放置新运算符,具有数据成员初始化以及与普通新运算符的差异
- 如何为显式重载构造函数启用复制初始化
- C++:初始化变量;重载隐式构造函数
- 初始化程序列表和赋值重载(运算符=)
- 使用类模板初始化下标重载函数中的引用类型无效
- C++11统一初始化和函数重载
- 函数重载与函数变量初始化
- 我可以将隐式初始化重载为 0 吗?
- 当实参是初始化列表而形参是引用时,重载解析
- 从构造函数初始化列表调用重载构造函数
- 在c++中重载全局new()调用之前未初始化全局静态变量