std :: string & amp; в качестве параметра шаблона и abi_tag в 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)

Это ошибка в компиляторе? Или это ожидаемое поведение?
Какой может быть обходной путь?

4

Решение

Это определенно ошибка компилятора; Я не могу найти точную ошибку в 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

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]