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

Cur*_*ous 4 c++ constructor c++11 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;
}
Run Code Online (Sandbox Code Playgroud)

我得到以下输出

Something()
Something()
Something(SomethingType&&)
Run Code Online (Sandbox Code Playgroud)

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

son*_*yao 5

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

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

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

因为复制构造函数将const Something&其作为参数。这意味着对于要调用的复制构造函数,添加const限定符需要隐式转换。但是转发引用构造函数可以被实例化以Something&作为它的参数,那么它是一个精确匹配并且在重载决议中获胜。

因此,如果您 make something const,将在第三种情况下调用隐式定义的复制构造函数,而不是转发引用构造函数。

居住

但不是移动构造函数?

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

  • 我发现在理解这些问题方面非常有用的一本书是 Scott Meyers 的 [Effective Modern C++](http://shop.oreilly.com/product/0636920033707.do)。 (3认同)