为什么使用rvalue引用参数移动模板方法会给出未解析的外部符号错误?

时间:2015-08-14 18:21:04

标签: c++ c++11

这是一个简单的类来说明问题:

class ClassA
{
public:
    template<typename T>
    void Method1(T&& a) {};
};

然后在我的主要:

    double a = 0;

    ClassA classA;
    classA.Method1(a);

编译好。但是当我将Method1实现移动到cpp文件时,就像这样......

部首:

class ClassA
{
public:
    template<typename T>
    void Method1(T&& a);
};

实现:

template<typename T>
void ClassA::Method1(T&& a) {}

template void ClassA::Method1<double>(double&&);

我在Visual Studio 2013中收到错误消息

  

错误LNK2019:未解析的外部符号&#34; public:void __thiscall ClassA :: Method1(double&amp;)&#34;函数_wmain中引用了(?? $ Method1 @ AAN @ClassA @@ QAEXAAN @ Z)

现在,如果在主要内容中我将Method1的调用替换为 classA.Method1(std::move(a))

它编译得很好。为什么只有头文件版本在没有std::move的情况下编译得很好,而带有实现的版本需要编译std::move

2 个答案:

答案 0 :(得分:1)

在:

template <typename T>
void Method1(T&& a);

T&&转发参考,而非右值参考

现在,电话:

classA.Method1(a);

T推断为double&。您提供的显式实例化:

template void ClassA::Method1<double>(double&&);

仅适用于 rvalue 表达式。这就是当您使用astd::move转换为 xvalue (一种右值)时编译和链接的原因。

尝试以下显式实例化:

template void ClassA::Method1<double&>(double&);

但是,您还没有涵盖转发引用可以采用的所有可能性,因此最好将Method1的实现移动到带有类定义的头文件。

答案 1 :(得分:0)

您为显式实例化提供的参数不正确。左值实例化将是Method1<double&>(double&);