c++ - 使用左值引用错误地调用了右值引用构造函数

标签 c++ c++11 rvalue-reference

当我编译这段代码时:

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;
}

我收到编译器消息:

在 C::C(T&&) 的实例化中 [其中 T = Base&]':需要 C ca(base);错误:new 无法应用于引用类型

在 C::C(T&&) 的实例化中 [其中 T = Derived&]':需要 C cb(衍生);错误:new 无法应用于引用类型

看起来C ca(base);与右值引用构造函数调用相关联。为什么编译器很难将这一行与第一个构造函数关联起来?如果我注释掉有问题的行,cccd 的构造将按预期工作。

最佳答案

如果您要复制移动,请按值传递。简单来说:

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

否则,如果您有一个通用引用,如 template <typename T> ... T && ,您可以获得基本类型为 typename std::decay<T>::type (来自<type_traits>)。在这种情况下,您应该将参数传递为 std::forward<T>(inBase) .

关于c++ - 使用左值引用错误地调用了右值引用构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18151065/

相关文章:

c++ - RValue、模板解析和复制构造函数(在 Visual C++ 2010 中)

c++ - 父进程如何用一个管道向 n 个子进程发送消息?

c++ - 是否可以将所有权从 void* 转移到 unique_ptr?

c++ - 为可变参数模板编写基本案例

c++ - C++中的评估顺序初始化数组

c++ - move 构造函数和静态数组

c++ - (c++23 隐式 move ) 将 move 的本地存储变量作为仅带括号的右值引用返回?

c++ - 在调用之前检查 std::function 的有效性?

c++ - 是否有静态分析器可以检查 C/C++/Objective-C 中的局部变量重新分配?

c++ - 如何在 C++ 中返回 NULL 对象