所以我正在更新一些使用gcc-11的C++11代码,并且遇到了一个问题.
也就是说,在gcc-11中,如果构造函数使用在匿名命名空间中定义的模板类中的类型,则类的构造函数符号(显式实例化)不存在。
产生此问题的简化示例如下所示。
Clang-12和gcc-8没有表现出这种行为并输出符号(正如我所预料的)。
template.h:
#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:
#include "template.h"
template <typename T>
MyTemplateClass<T>::MyTemplateClass(const BaseType* array)
{
}
template class MyTemplateClass<float>;使用编译命令
gcc -c -o template.o template.cpp使用nm,我得到了Clang-12和gcc-8的下列符号输出:
0000000000000000 W MyTemplateClass<float>::MyTemplateClass(float const*)
0000000000000000 W MyTemplateClass<float>::MyTemplateClass(float const*)
0000000000000000 n MyTemplateClass<float>::MyTemplateClass(float const*)对于gcc-11,我只得到一个文本符号:
0000000000000000 t MyTemplateClass<float>::MyTemplateClass(float const*)如果我在标题中将显式专业化标记为extern,那么在gcc-11中,事情就会再次发生作用。ie,加:
extern template class MyTemplateClass<float>;所以我想我的问题是:这是预期的行为,而它以前起作用的事实仅仅是因为它没有定义,还是这是某种形式的错误编译?
发布于 2022-04-24 08:05:33
通常不应在头文件中使用匿名命名空间。这种情况很少有例外,而且您的用例不是一个。您可以使用namespace detail向人们建议,代码中的代码并不意味着他们可以使用。
GCC 11在这里没有做错什么,您的代码根本不是可移植的。
https://stackoverflow.com/questions/71985273
复制相似问题