![](/img/trans.png)
[英]Non type template parameter of type std::string& compiles in gcc but not in clang
[英]std::string & as template parameter and abi_tag in gcc 5
考慮以下代碼段(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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.