我写了一些代码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';
}
输出为:
5
0
我的问题是:
operator=(int)
,而不是“歧义”或另一个? S
? 我的意图是
s = S{};
。如果可行,编写s = {};
会很方便。我目前正在使用s = decltype(s){};
,但我希望避免重复输入类型或变量名。 最佳答案
{}
到int
是身份转换([over.ics.list]/9)。 {}
到S
是用户定义的转换([over.ics.list]/6)(从技术上讲,它是{}
到const S&
的转换,先经过[over.ics.list]/8和[over.ics.ref],然后再返回[over.ics。列表]/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; }
如果要启用转换,可以使用不同的约束(在这种情况下,您可能还希望通过引用接受参数)。
关键是,通过将正确的操作数的类型设为模板参数,可以阻止
t = {}
使用此重载-因为{}
是非推论上下文。template<class T> T default_constructed_instance_of(const T&) { return {}; }
和s = default_constructed_instance_of(s);
是否计数?关于c++ - 重载分辨率: assignment of empty braces,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33511641/