c – std :: string&作为模板参数和gcc 5中的abi_tag

考虑以下代码段(test1.cpp):

#include <string>

extern std::string test_string;

template<std::string &s>
class test{
public:
   static void bar(){ }
};

std::string test_string("test string");
void foo(){test<test_string>::bar();}

现在让我们切换最后两行代码(test2.cpp)的顺序:

#include <string>

extern std::string test_string;

template<std::string &s>
class test{
public:
   static void bar(){ }
};

void foo(){test<test_string>::bar();}
std::string test_string("test string");

什么都不应该改变.但是如果你通过objdump查看编译文件,你会发现不同之处:

objdump -t -C test*.o | grep bar

在一个案例中,模板测试被实例化为:

test<test_string[abi:cxx11]>::bar()

在另一个作为:

test<test_string>::bar()

两个文件都只是使用编译

gcc -c test*.cpp

因此,将std :: string作为模板参数的引用视为未标记,如果它只是声明为extern.并且它在定义后被视为标记.

我的项目中的一些类被实例化两次,其中应该只有一个类.这是相当不愉快的.

gcc version 5.2.1 20151010 (Ubuntu 5.2.1-22ubuntu2)

这是编译器中的错误吗?或者是预期的行为?
 什么是解决方法?

最佳答案 这绝对是一个编译器错误;我找不到GCC Bugzilla中的确切错误,但它看起来与
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66971类似 – 虽然更简单,因为它不需要使用thread_local关键字,它可能具有相同的根本原因.

作为一种解决方法,似乎将引用模板参数更改为指针将使其工作:

template<std::string *s> class test { .... };
void foo(){test<&test_string>::bar();}

编辑:我已经将此错误与gcc一起提交为https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69621

点赞