10

在我发现 MSVC 和 GCC 之间在编译和链接相同代码时不一致(可能也是 clang)之后,我很好奇这个程序是否真的编译和链接,因此它是 MSVC 中的错误(报告链接器错误)或应该我写的不一样。该程序由3个文件组成:

通道

template <typename T>
struct A
{
    void func() {};
};

template <>
void A<int>::func ();

A.cpp:

#include "C.h"
int main()
{
    A<int> x;
    x.func();
}

B.cpp:

#include "C.h"
template <>
void A<int>::func()
{
}

MSVC 产生的链接器错误是:

A.obj:错误 LNK2019:未解析的外部符号“public:void __thiscall A::func(void)”

所以基本上它决定不创建符号超出定义放置在B.cpp. 让我强烈怀疑它是一个错误的事情是,将非专业定义func移出结构定义,甚至将其置于专业化声明之上,使程序链接成功,但我想确定。

所以我的问题是 - 这个程序是否应该由符合标准的编译器/链接器编译和链接而没有错误?

4

2 回答 2

1

从标准:

© ISO/IEC N4527 14.6.4.1 实例化点 [temp.point] 1 对于函数模板特化、成员函数模板特化或类模板的成员函数或静态数据成员的特化,如果特化是隐式的实例化,因为它是从另一个模板特化中引用的,并且引用它的上下文取决于模板参数,所以特化的实例化点是封闭特化的实例化点。否则,这种特化的实例化点紧跟在引用特化的命名空间范围声明或定义之后

在这种情况下,我认为这意味着在 Ch 出现“范围声明”。如果是这种情况,那么您的代码应该与符合标准的工具链链接。我可能会误解这...

于 2015-09-06T12:25:49.630 回答
-2

未命名的命名空间具有内部链接。由于模板特化在一个未命名的命名空间内,它也有内部链接。

要解决此问题,请将模板放在命名空间中或将特化指定为“extern”。

于 2015-09-06T17:16:52.473 回答