这是一个简单的类来说明问题:
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
?
答案 0 :(得分:1)
在:
template <typename T>
void Method1(T&& a);
T&&
是转发参考,而非右值参考。
现在,电话:
classA.Method1(a);
将T
推断为double&
。您提供的显式实例化:
template void ClassA::Method1<double>(double&&);
仅适用于 rvalue 表达式。这就是当您使用a
将std::move
转换为 xvalue (一种右值)时编译和链接的原因。
尝试以下显式实例化:
template void ClassA::Method1<double&>(double&);
但是,您还没有涵盖转发引用可以采用的所有可能性,因此最好将Method1
的实现移动到带有类定义的头文件。
答案 1 :(得分:0)
您为显式实例化提供的参数不正确。左值实例化将是Method1<double&>(double&);
。