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

Why is forwarding reference constructor called instead of copy 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&&)

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

I am guessing that it's because the move constructor was implicitly defined but not the copy constructor.

不,两者都是为 class Something.

隐式定义的

Why is the copy constructor being resolved to the templated forwarding reference constructor

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

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

LIVE

but not the move constructor?

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