我正在使用 C++ 外部模板来加快编译速度。我注意到 Visual Studio 2012 在处理extern template
. 这是一个例子:
主.cpp:
#include <iostream>
#include "Calc.h"
using namespace std;
int main(int argc, char** argv)
{
Calc<int> c1;
cout << c1.add(1, 2) << endl;
}
计算.h:
#pragma once
template <class A_Type>
class Calc
{
public:
A_Type add(A_Type x, A_Type y)
{
return x + y;
}
};
extern template class Calc<int>;
通常我会包含Calc.cpp,template class Calc<int>;
确保模板只实例化一次。对于这个例子,我只编译Main.cpp并期望它失败。
问题是,Visual Studio 2012 会愉快地编译和链接上面的代码。它不尊重extern template
. 我发现的唯一解决方案是在标题中执行此操作:
计算.h:
#pragma once
template <class A_Type>
class Calc
{
public:
A_Type add(A_Type x, A_Type y);
};
template <class A_Type> A_Type Calc<A_Type>::add(A_Type x, A_Type y)
{
return x + y;
}
extern template class Calc<int>;
如果标头是这样的,则 Visual Studio 无法链接(如预期的那样,抱怨缺少 的定义Calc<int>::add
)。但是,g++ 4.6.3无法链接这些示例中的任何一个。
谁是对的?如果一个类中函数的原型和定义都在同一个头文件中指定,真的有区别吗?有没有办法指定“较短形式”的Calc.h并让它在 Visual Studio 2012(以及 gcc)中按预期失败?