首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用LLVM-Clang隐式实例化私有C++模板的链接器错误

用LLVM-Clang隐式实例化私有C++模板的链接器错误
EN

Stack Overflow用户
提问于 2014-07-03 12:07:12
回答 1查看 911关注 0票数 4

免责声明:我知道模板是,通常是在头文件中实现的。请通读.

我有一个与C++模板相关的问题。我的代码在Windows下使用MSVC构建,但在Mac下不使用LLVM,但我不确定哪一个是错误的。

下面是一个简单的测试用例,由三个源文件组成:

  • main.cpp #包括"templ.h“int main() { templ(1);返回0;}
  • templ.h 模板T templ(const T&);
  • templ.cpp #包括"templ.h“模板T templ(const T& t) {返回t;}/显式实例化模板int templ(const int&);//隐式实例化void (){ templ(1);}

如您所见,我希望函数模板的实现是私有的(即隐藏在.cpp文件中)。为了允许这样做,我必须在与其定义相同的翻译单元中实例化我的模板。在上面的例子中,我只实例化templ<int>。AFAIK,这是不寻常的,但完美的作物C++。

实际上,这段代码是用两个编译器构建的。但是,如果我注释掉显式实例化而只保留隐式实例化,编译器的行为就会有所不同。MSVC成功构建,但LLVM在以下链接器错误中失败:

代码语言:javascript
复制
Undefined symbols for architecture x86_64:
  "int templ<int>(int const&)", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture x86_64

此外,只有在启用优化(例如-02)时才会发生该错误。

标准是怎么说的?这是LLVM已知的行为/bug吗?

我的LLVM版本是:

代码语言:javascript
复制
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix

对不起,如果这是一个副本。很难选择正确的关键字。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-03 15:08:15

这是正常的,也是预料之中的。

14个模板 6.类模板的函数模板、类模板的成员函数或类模板的静态数据成员应在隐式实例化(14.7.1)的每个翻译单元中定义,除非相应的专门化在某些翻译单元中显式实例化(14.7.2);不需要诊断。

对于您的情况,这意味着当删除templ的显式实例化时,编译器可以

  1. 通常由于同一TU中的隐式实例化而生成实例化;或
  2. 内联对templ的调用,不生成任何外部可用的实体。

这两种行为都可以用于符合规范的实现。如果您确保某个地方有一个显式实例化,那么任何一个都会生成有效的对象代码。如果你不这样做,你可能会犯错,也可能不会出错,这是你自己的错。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24553297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档