C++显式通用引用构造函数不隐藏拷贝构造函数?

标签 c++ c++11 copy-constructor universal-reference

大概是我对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
}

DEMO

这是一个通用的解决方案,而不是 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/

相关文章:

c++ - 编译如何选择调用哪个构造函数?

c++ - 如何从构造函数返回错误代码?

c++ - 使用 () 的 POD 成员类型的构造函数初始化列表

c++ - 为什么我需要类型 T 的复制构造函数?

c++ - 复制构造函数调用 C++

c++ - 是否有异常(exception)规则,如果地址可以使用&它是左值找到?

c++ - 增加线程数时出现 CUDA 内核错误

c++ - 在 C++ 中,如何调用在抽象基类和派生类中都有定义的基类的虚函数定义?

c++ - 如何在用Boost MSM编写的状态机中直接达到任何状态

c++ - std::unordered_set::equal_range 迭代器问题