为什么调用转发引用构造函数而不是复制构造函数?

时间:2017-04-09 14:17:09

标签: c++ c++11 constructor c++14 implicit-constructor

给出以下代码

#include <iostream>

using namespace std;

template <typename Type>
struct Something {
    Something() {
        cout << "Something()" << endl;
    }

    template <typename SomethingType>
    Something(SomethingType&&) {
        cout << "Something(SomethingType&&)" << endl;
    }
};

int main() {
    Something<int> something_else{Something<int>{}};
    auto something = Something<int>{};
    Something<int>{something};
    return 0;
}

我得到以下输出

Something()
Something()
Something(SomethingType&&)

为什么复制构造函数被解析为模板化转发引用构造函数而不是移动构造函数?我猜它是因为移动构造函数是隐式定义的,而不是复制构造函数。但是在阅读了堆栈溢出中没有隐式定义复制构造函数的情况后,我仍然感到困惑。

1 个答案:

答案 0 :(得分:4)

  

我猜这是因为移动构造函数是隐式定义的,而不是复制构造函数。

不,两者都是为类Something隐式定义的。

  

为什么要将复制构造函数解析为模板化转发引用构造函数

因为复制构造函数将const Something&作为参数。这意味着要调用复制构造函数,需要隐式转换才能添加const限定符。但转发引用构造函数可以实例化为Something&作为参数,然后它是完全匹配并在重载决策中获胜。

因此,如果您创建something const,则将针对第3个案例而不是转发引用构造函数调用隐式定义的复制构造函数。

LIVE

  

但不是移动构造函数?

因为对于移动构造函数,上述问题无关紧要。对于第一和第二种情况的调用,隐式定义的移动构造函数和转发引用构造函数都是精确匹配,然后非模板移动构造函数获胜。