Rei*_*ica 9 c++ explicit implicit-conversion uniform-initialization
假设我有一个FunctionWrapper像这样定义的类:
struct FunctionWrapper
{
FunctionWrapper(std::function<void()> f);
// ... plus other members irrelevant to the question
};
Run Code Online (Sandbox Code Playgroud)
我想,以防止隐式转换std::function<void()>到FunctionWrapper,但允许构建FunctionWrapper使用括号初始化语法(即使用初始化列表用一个参数).换句话说,我想这样:
void foo();
void wrap(FunctionWrapper);
wrap(foo); // (1) error
wrap({foo}); // (2) OK
wrap(FunctionWrapper{foo}); // (3) OK
Run Code Online (Sandbox Code Playgroud)
有没有办法实现这一目标?我上面定义类的方法不是它:这允许隐式转换,因此(1)编译.
如果我添加explicit到构造函数:
struct FunctionWrapper
{
explicit FunctionWrapper(std::function<void()> f);
// ... plus other members irrelevant to the question
};
Run Code Online (Sandbox Code Playgroud)
它也没有帮助,因为它"太过分"并且不允许(2)以及(1).
有没有办法实现"中间地带"并且(2)编译而(1)产生错误?
有没有办法实现这一目标?
是.你已经拥有它了.
wrap(foo);
Run Code Online (Sandbox Code Playgroud)
为此,它将涉及两个用户定义的转换:void(*)() --> std::function<void()> --> FunctionWrapper但我们最多只允许一个用户定义的转换.所以这是一个错误,除非你添加一个单独的构造函数FunctionWrapper来允许它.
wrap({foo});
Run Code Online (Sandbox Code Playgroud)
这已经很好了,我们是复制列表初始化FunctionWrapper所以上述限制不适用.
wrap(FunctionWrapper{foo});
Run Code Online (Sandbox Code Playgroud)
这显然很好.
请注意,这也为您的第一个示例实际工作的情况提供了前进的路径.假设你有:
struct Wrapper {
Wrapper(int ) { }
};
foo(0); // want this to fail
foo({0}); // want this to be OK
foo(Wrapper{0}); // ... and this
Run Code Online (Sandbox Code Playgroud)
你不能创建构造函数explicit,因为这foo({0})也会导致失败.但是你可以简单地用另一个包装器添加另一层间接:
struct AnotherWrapper {
AnotherWrapper(int i): i{i} { }
int i;
};
struct Wrapper {
Wrapper(AnotherWrapper ) { }
};
Run Code Online (Sandbox Code Playgroud)
在这里,wrap(0)出现故障,但wrap({0})并wrap(Wrapper{0})都OK.
| 归档时间: |
|
| 查看次数: |
193 次 |
| 最近记录: |