【发布时间】:2012-12-14 05:49:11
【问题描述】:
考虑以下头文件和源文件:
// main.cpp
#include "myClass.h"
int main()
{
MyClass m;
m.foo<double>();
m.foo<float>();
}
// myClass.h
#pragma once
#include <iostream>
using namespace std;
class MyClass
{
public:
template <typename T>
void foo()
{
cout << "Template function<T> called" << endl;
}
template <>
void foo<int>()
{
cout << "Template function<int> called" << endl;
}
template <>
void foo<float>();
};
// myClass.cpp
#include "myClass.h"
template <>
void MyClass::foo<float>()
{
cout << "Template function<float> called" << endl;
}
foo<float> 专业化出现链接错误。如果我将专业化的定义放在头文件中,那么一切都会按预期进行。
我认为原因可能是该方法没有显式实例化(尽管template class 的完全特化不需要显式实例化来正确链接)。如果我尝试显式实例化该方法,则会收到此错误:
error C3416: 'MyClass::foo' : 显式特化可能没有显式实例化
所以问题是:
- 有没有办法在
cpp文件中定义特化并正确链接? - 如果不是,为什么不呢?我可以显式实例化模板方法 不专业就好了。为什么完全专业化不一样?
【问题讨论】:
-
@billz:这不是重复的(或者我不擅长搜索......但我和我的同事搜索了很长时间)。关于类专业化和
template function专业化有很多问题,但当类是非模板(这有关系吗?)并且template method是完整专业化时则不会。 -
@billz:关于您的重复链接,这是一个关于使用模板链接错误的一般问题。我已经知道显式实例化类模板和模板方法的技巧。这里的问题是
full对template method的特化。 -
显示我的工具链是多么陈旧(Apple LLVM 4.1,supposed 兼容 C++11),因为此代码中的头文件本身不会t 为我编译;在第一个类内特化时出现 ("Explicit specialization of 'foo' in class scope") 的错误。
-
@WhozCraig Gcc 4.7.2 也不会编译,但 VS2012 可以编译
-
@didierc:绝对可以将模板的定义放在单独的翻译单元中。您需要做的就是显式地实例化它:stackoverflow.com/a/4933205/368599 顺便说一句,这让我感到困惑,因此提出了这个问题。为什么完全专业化的模板方法不受这些规则的约束?