M.M*_*M.M 8 c++ overload-resolution c++11
我写了一些代码S s;
...... s = {};
,期待它最终结果一样S s = {};
.但事实并非如此.以下示例再现了该问题:
#include <iostream>
struct S
{
S(): a(5) { }
S(int t): a(t) {}
S &operator=(int t) { a = t; return *this; }
S &operator=(S const &t) = default;
int a;
};
int main()
{
S s = {};
S t;
t = {};
std::cout << s.a << '\n';
std::cout << t.a << '\n';
}
Run Code Online (Sandbox Code Playgroud)
输出是:
5
0
Run Code Online (Sandbox Code Playgroud)
我的问题是:
operator=(int)
选择这里,而不是"模棱两可"或另一个?S
?我的意图是s = S{};
.s = {};
如果有效,写作会很方便.我目前正在使用s = decltype(s){};
但是我宁愿避免重复类型或变量名称.
T.C*_*.C. 11
为什么
operator=(int)
选择这里,而不是"模棱两可"或另一个?
{}
to int
是身份转换([over.ics.list]/9).{}
到S
是一个用户定义的转换([over.ics.list]/6)(在技术上,它是{}
到const S&
,并且通过[over.ics.list]/8并进入[over.ics.ref]第一回来之前[ over.ics.list]/6).
第一场胜利.
有一个整洁的解决方法吗?
诀窍的变化std::experimental::optional
使得t = {}
总是变t
空.关键是要制作operator=(int)
一个模板.如果你想接受int
,仅int
,然后就变成
template<class Int, std::enable_if_t<std::is_same<Int, int>{}, int> = 0>
S& operator=(Int t) { a = t; return *this; }
Run Code Online (Sandbox Code Playgroud)
如果要启用转换,可以使用不同的约束(在这种情况下,您可能还希望通过引用获取参数).
关键是通过使右操作数的类型成为模板参数,您可以阻止t = {}
使用此重载 - 因为它{}
是一个非推导的上下文.
......没有改变
S
?
是否template<class T> T default_constructed_instance_of(const T&) { return {}; }
再s = default_constructed_instance_of(s);
算吗?
归档时间: |
|
查看次数: |
589 次 |
最近记录: |