使用左值引用错误地调用右值引用构造函数

Fad*_*mic 1 c++ rvalue-reference c++11

当我编译这段代码时:

class Base { /*...*/ };
class Derived : public Base { /*...*/ };

class C
{
public:
    template<typename T>
    C(T const& inBase) : baseInC(new T(inBase)) { /*...*/ }

    template<typename T>
    C(T&& inBase) : baseInC(new T(std::move(inBase))) { /*...*/ }

    std::unique_ptr<Base> baseInC;
};

int main()
{
    Base base;
    Derived derived;

    C ca(base);
    C cb(derived);

    C cc( (Base()) );
    C cd( (Derived()) );

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到一个编译器消息:

In instantiation of C::C(T&&) [with T = Base&]': required from C ca(base); error: new cannot be applied to a reference type

In instantiation of C::C(T&&) [with T = Derived&]': required from C cb(derived); error: new cannot be applied to a reference type

它看起来C ca(base);与右值参考ctor调用相关联.为什么编译器难以将此行与第一个ctor相关联?如果我注释掉违规行,那么构建cc和cd工作就像预期的那样.

Ker*_* SB 5

如果您要复制或移动,请按值传递.以简化的方式:

template <typename T>
void foo(T x)
{
    T * p = new T(std::move(x));
}
Run Code Online (Sandbox Code Playgroud)

否则,如果您有类似的通用引用template <typename T> ... T &&,则可以将基类型作为typename std::decay<T>::type(from <type_traits>).在这种情况下,您应该将参数传递为std::forward<T>(inBase).