大概是我对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>
,参见 here )?
最佳答案
在A
,复制构造函数未隐藏。编译器一如既往地隐式声明它。它只是失去重载决议,因为它的参数类型(const A&
)与构造函数模板特化的参数(A&
)相比有额外的cv限定。如果你愿意的话
auto b = static_cast<const A&>(a);
您会看到将调用复制构造函数。
在A_explicit
, 该模板根本没有作为重载决议的候选者提交,因为它被声明为 explicit
.隐式声明的复制构造函数仍然存在,就像在 A
中一样。 , 故称。
关于C++显式通用引用构造函数不隐藏拷贝构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30117866/