可能我的理解explicit
还不够,但是我想知道为什么在以下代码中,当我将通用声明构造函数声明为时,通用构造函数不会将副本构造函数隐藏explicit
。
struct A
{
A() = default;
template<typename T>
A(T&& t) { std::cout<<"hides copy constructor"<<std::endl; }
};
struct A_explicit
{
A_explicit() = default;
template<typename T>
explicit A_explicit(T&& t) { std::cout<<"does not hide copy constructor?"<<std::endl; }
};
int main()
{
A a;
auto b = a; (void) b; //prints "hides copy constructor"
A_explicit a_exp;
auto b_exp = a_exp; (void) b_exp; //prints nothing
}
这是一种通用解决方案,而不是SFINAE的解决方案,否则将用于防止隐藏A
(例如,通过std::enable_if_t<!std::is_same<std::decay_t<T>, A>::value>
,请参见此处)吗?
标记为的构造函数explicit
在复制初始化期间(A a = b;
等等)不参与重载解析。
它确实参与了复制列表初始化(A a = {b1};
),并且如果选择该程序,将导致该程序的格式不正确。
...除了括号内的东西是一个A
或从中派生的类外,在这种情况下,最近的缺陷报告更改了规则,说在这种特殊情况下将执行复制初始化,因此explicit
再次忽略了构造函数完全。
我知道,这很容易教。
这是一种通用解决方案,而不是SFINAE的解决方案,否则将用于防止隐藏在A中吗?
不会。因为该构造函数仍将赢得直接初始化的重载解析:
A_explicit a, b(a); // will call the constructor taking a forwarding reference
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句