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

 戴劳力士_484 发布于 2023-01-06 15:07

免责声明:我知道模板通常在头文件中实现.请仔细阅读.

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

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

main.cpp中

#include "templ.h"

int main()
{
   templ(1);
   return 0;
}

templ.h

template
T templ(const T&);

templ.cpp

#include "templ.h"

template
T templ(const T& t)
{
   return t;
}

//explicit instantiation
template int templ(const int&);

//implicit instantiation
void f()
{
   templ(1);
}

如您所见,我希望函数模板的实现是私有的(即隐藏在.cpp文件中).为此,我必须在与其定义相同的翻译单元中实例化我的模板.在上面的例子中,我只是实例化templ.AFAIK,这是不寻常的,但完全是cromulent C++.

因此,此代码与两个编译器一起构建.但是,如果我注释掉显式实例化并且只保留隐式实例化,则编译器的行为会有所不同.MSVC成功构建,但LLVM-Clang因以下链接器错误而失败:

Undefined symbols for architecture x86_64:
  "int templ(int const&)", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture x86_64

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

标准对此有何看法?这是LLVM-Clang的已知行为/错误吗?

我的LLVM-Clang版本是:

Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix

对不起,如果这是重复的.选择正确的关键字非常困难.

1 个回答
  • 这是正常的和预期的.

    14模板
    6除非明确实例化相应的专业化,否则应在每个隐式实例化它的翻译单元中定义一个函数模板,类模板的成员函数,变量模板或类模板的静态数据成员(14.7.1). (14.7.2)在某些翻译单位; 无需诊断.

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

      通常由于同一TU中的隐式实例化而生成实例化; 要么

      内联调用templ 而不生成任何外部可用实体.

    对于符合要求的实现,允许任何行为.如果确定在某处有显式实例化,则要么生成有效的对象代码.如果不这样做,您可能会或可能不会收到错误,这是您自己的错.

    2023-01-06 15:09 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有