Я сделал попытку минимального теста. Этот случай передается по rhel-7 с devtoolset-4 (gcc-5.2) и завершается неудачей при rhel-6. Статус -2 указывает на то, что «mangled_name не является допустимым именем по правилам искажения C ++ ABI». https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html
Я все делаю неправильно или это ошибка, которую мне придется как-то обойти, если я хочу использовать gcc-5.2 на RHEL-6? Если да, то какие рекомендации? Моя лучшая мысль до сих пор состоит в том, чтобы переопределить «IJ» в искаженном имени в «II», прежде чем передать его в __cxa_demangle (). Если это может быть относительно надежным, я могу жить с этим.
#include <iostream>
#include <string>
#include <tuple>
#include <typeinfo>
#include <cxxabi.h>
#define DUMP(x) std::cout << #x << " is " << x << std::endl
template<typename T>
void print_type(T t)
{
int status;
auto name = typeid(t).name();
DUMP(name);
auto thing2 = abi::__cxa_demangle(name, 0, 0, &status);
if(status == 0)
{
DUMP(thing2);
}
else
{
std::cout << typeid(t).name() << " failed to demangle\n";
DUMP(status);
}
}
typedef std::tuple<foo_t, foo_t> b_t;
int main(int argc, char **argv)
{
std::tuple<bool, bool> t;
print_type(t);
}
Выход Centos-6
name is St5tupleIJbbEE
St5tupleIJbbEE failed to demangle
status is -2
Выход Centos-7
name is St5tupleIJbbEE
thing2 is std::tuple<bool, bool>
Выход Centos-6 с devtoolset-3 (gcc-4.9)
name is St5tupleIIbbEE
thing2 is std::tuple<bool, bool>
std::string typestring(typeid(T).name());
auto pos = typestring.find("IJ");
if(pos != std::string::npos)
{
// gcc-5.2 uses IJ in typestring where
// gcc-4.9 used II - this fugly hack makes
// cxa_demangle work on centos/rhel-6 with gcc-5.2
// eg std::tuple<bool, bool>
typestring[pos + 1] = 'I';
}
rv = abi::__cxa_demangle(typestring.c_str(), 0, 0, &status);
Других решений пока нет …