Visual C++中的外部模板是否存在错误
Is there a bug with extern template in Visual C++?
给定此代码:
//header.h
template <class T>
class Foo
{
public:
Foo(T t) : t(t) {}
T t;
};
//source1.cpp:
#include "header.h"
extern template class Foo<int>;
int main()
{
Foo<int> f(42);
}
根据我的理解,这个程序不应该链接,因为任何地方都不应该有class Foo<int>
的定义(extern template
应该防止这种情况发生)。然而,使用VC++11(Visual Studio 2012),它确实可以编译和链接。在GCC中,它没有:
source1.cpp:(.text+0x15): undefined reference to `Foo<int>::Foo(int)'
然而,如果我链接到source2.cpp,它会起作用(正如我所期望的那样):
#include "header.h"
template class Foo<int>;
根据这篇博客文章,extern模板从VC10开始就应该得到支持。http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx
顺便说一句,有没有一种方法可以在Windows/ViewStudio上列出对象文件中的名称?在Linux上我会做:
$ nm source1.o
U _ZN3FooIiEC1Ei <- "U" means that this symbol is undefined.
0000000000000000 T main
C++11 14.7.2/10"显式实例化"说:
除了内联函数和类模板专门化之外,显式实例化声明具有抑制它们引用的实体的隐式实例化。
类模板Foo<T>
中的构造函数是内联的。VS2012将以您期望的方式工作,如果您这样构建标题:
//header.h
template <class T>
class Foo
{
public:
Foo(T t);
T t;
};
template <class T>
Foo<T>::Foo(T t) : t(t)
{
}
因此构造函数不是内联的。
我上面引用的标准中的段落确实包括以下注释:
[注意:其意图是显式实例化声明仍然是隐式的在使用odr时实例化(3.2),以便可以考虑主体用于内联,但没有内联函数的行外副本将在翻译单元中生成。——尾注]
查看在内联ctor时创建的程序集代码,ctor的一个行外副本被放置在对象文件中(即使在编译带有优化的示例时从未调用过ctor),因此MSVC似乎没有遵循标准的意图。但是,说明并不规范,所以我认为MSVC的行为是符合要求的。
关于从使用MSVC构建的对象文件中转储符号的问题,您可以使用dumpbin
实用程序:
使用非内联构造函数编译示例时:
dumpbin /symbols test.obj
...
008 00000000 UNDEF notype () External | ??0?$Foo@H@@QAE@H@Z (public: __thiscall Foo<int>::Foo<int>(int))
^^^^^
...
使用内联的ctor:编译示例
00A 00000000 SECT4 notype () External | ??0?$Foo@H@@QAE@H@Z (public: __thiscall Foo<int>::Foo<int>(int))
^^^^^
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 如何检查QList中是否存在值
- 根据某个函数是否存在启用模板
- 地图计数确实很重要,或者只是检查是否存在
- C++中是否存在 std::conditional 的懒惰等价物?
- 无论如何,我可以确定构造函数是否存在吗?
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- 堆分配的对象是否存在永不为空的唯一所有者?
- 扩展类中的可选 vir 函数,测试它在运行时是否存在
- 模板化检查是否存在带有参数列表的类成员函数?
- 是否存在包含负号的isdigit函数(过载)
- 如何巧妙地编写两个函数——一个用于检查是否存在解决方案,另一个用于获取所有解决方案
- 检查编译时是否存在静态函数
- 向量是否存在行主要形式?
- 检查 TinyXML 中的元素是否存在
- 检测是否存在具有 C++17 的类成员
- 虚拟继承中是否存在多重继承?
- 我遇到了这个代码片段,不明白. 它递归检查 C++ 字符串中是否存在大写字符
- std::weak_ptr 和相应的 std::shared_ptr 之间是否存在数据竞争?
- 是否存在用于 C 或 C++ 中常见数学运算(例如最小值、最大值和平均值)的可导入库?