首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模板和匿名命名空间问题

模板和匿名命名空间问题
EN

Stack Overflow用户
提问于 2022-04-24 03:27:01
回答 1查看 158关注 0票数 1

所以我正在更新一些使用gcc-11的C++11代码,并且遇到了一个问题.

也就是说,在gcc-11中,如果构造函数使用在匿名命名空间中定义的模板类中的类型,则类的构造函数符号(显式实例化)不存在。

产生此问题的简化示例如下所示。

Clang-12和gcc-8没有表现出这种行为并输出符号(正如我所预料的)。

template.h:

代码语言:javascript
复制
#pragma once

namespace {
   template <typename T>
   struct MyAnonTempStruct
   {
      typedef float BaseType;
   };
}

template <typename T>
class MyTemplateClass
{
   public: 
   typedef typename MyAnonTempStruct<T>::BaseType BaseType;

   public: 
   MyTemplateClass(const BaseType* array);
};

template.cpp:

代码语言:javascript
复制
#include "template.h"

template <typename T>
MyTemplateClass<T>::MyTemplateClass(const BaseType* array)
{
}

template class MyTemplateClass<float>;

使用编译命令

代码语言:javascript
复制
gcc -c -o template.o template.cpp

使用nm,我得到了Clang-12和gcc-8的下列符号输出:

代码语言:javascript
复制
0000000000000000 W MyTemplateClass<float>::MyTemplateClass(float const*)
0000000000000000 W MyTemplateClass<float>::MyTemplateClass(float const*)
0000000000000000 n MyTemplateClass<float>::MyTemplateClass(float const*)

对于gcc-11,我只得到一个文本符号:

代码语言:javascript
复制
0000000000000000 t MyTemplateClass<float>::MyTemplateClass(float const*)

如果我在标题中将显式专业化标记为extern,那么在gcc-11中,事情就会再次发生作用。ie,加:

代码语言:javascript
复制
extern template class MyTemplateClass<float>;

所以我想我的问题是:这是预期的行为,而它以前起作用的事实仅仅是因为它没有定义,还是这是某种形式的错误编译?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-24 08:05:33

通常不应在头文件中使用匿名命名空间。这种情况很少有例外,而且您的用例不是一个。您可以使用namespace detail向人们建议,代码中的代码并不意味着他们可以使用。

GCC 11在这里没有做错什么,您的代码根本不是可移植的。

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

https://stackoverflow.com/questions/71985273

复制
相关文章

相似问题

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