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 次 |
| 最近记录: |