GCC 4.1.1 не компилирует некоторый код с помощью tr1 :: unordered_map

У меня есть следующий код для проверки одной концепции из более крупной программы, и я пытаюсь скомпилировать с GCC 4.1.1 на Linux. Я не могу использовать более новую версию компилятора из-за ограничений корпоративной среды, поэтому мне нужно сделать так, чтобы он компилировался и работал с текущей доступной версией компилятора.

// test.cpp - my tr1::unordered_map usage example
#include <iostream>
#include <tr1/unordered_map>

namespace YY {

class X { public: X(int z_val = 0); private: int z; };
inline X::X(int z_val) : z(z_val) {}

enum XTE { Xt1, Xt2, Xt3 };

}

namespace std { namespace tr1 {

#define _my_tr1_hashtable_define_trivial_hash(T)        \
template<>                                            \
struct hash<T>                                      \
: public std::unary_function<T, std::size_t>        \
{                                                   \
std::size_t                                       \
operator()(T val) const                           \
{ return static_cast<std::size_t>(val); }         \
}

_my_tr1_hashtable_define_trivial_hash(YY::XTE);

#undef _my_tr1_hashtable_define_trivial_hash
}}namespace YY {
typedef std::tr1::unordered_map<long long, X*> TXM;
typedef std::tr1::unordered_map<XTE, TXM> TTXM;
}

int main()
{
YY::TTXM m;
std::cout << m.size();
return 0;
}

Затем я пытаюсь скомпилировать этот код, gcc выдает мне следующую ошибку:

$ g ++ -c test.cpp
/usr/lib/gcc/x86_64-redhat-linux/4.1.1/../../../../include/c++/4.1.1/tr1/hashtable: в экземпляре Б─≤Internal :: hash_code_base, Internal :: extract1st>, std :: equal_to, std :: tr1 :: hash, Internal :: mod_range_hashing, Internal :: default_ranged_hash, false> Б─≥:
/usr/lib/gcc/x86_64-redhat-linux/4.1.1/../../../../include/c++/4.1.1/tr1/hashtable:1014: создается из Б─≤std: : tr1 :: hashtable, std :: allocator>, Internal :: extract1st>, std :: equal_to, std :: tr1 :: hash, Internal :: mod_range_hashing, Internal :: default_ranged_hash, Internal :: prime_rehash_policy, false, false, правда> Б─≥
/usr/lib/gcc/x86_64-redhat-linux/4.1.1/../../../../include/c++/4.1.1/tr1/unordered_map:63: создается из Б─≤std: : tr1 :: unordered_map, std :: equal_to, std :: allocator>, false> Б─≥
/usr/lib/gcc/x86_64-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_pair.h:74: создан из Б─≤ std :: pair, std :: equal_to, std :: allocator>, false>> Б─≥
/usr/lib/gcc/x86_64-redhat-linux/4.1.1/../../../../include/c++/4.1.1/tr1/hashtable:413: создается из Б─≤Internal: : extract1st, std :: equal_to, std :: allocator>, false>>> Б─≥
/usr/lib/gcc/x86_64-redhat-linux/4.1.1/../../../../include/c++/4.1.1/tr1/hashtable:861: создается из Б─≤Internal: : hash_code_base, std :: equal_to, std :: allocator>, false>>, Internal :: extract1st, std :: equal_to, std :: allocator>, false>>>, std :: equal_to, std :: tr1 :: hash, Internal :: mod_range_hashing, Internal :: default_ranged_hash, false> Б─≥
/usr/lib/gcc/x86_64-redhat-linux/4.1.1/../../../../include/c++/4.1.1/tr1/hashtable:1014: создается из Б─≤std: : tr1 :: hashtable, std :: equal_to, std :: allocator>, false>>, std :: allocator, std :: equal_to, std :: allocator>, false>>>, Internal :: extract1st, std :: equal_to, std :: allocator>, false>>>, std :: equal_to, std :: tr1 :: hash, Internal :: mod_range_hashing, Internal :: default_ranged_hash, Internal :: prime_rehash_policy, false, false, true> Б─≥
/usr/lib/gcc/x86_64-redhat-linux/4.1.1/../../../../include/c++/4.1.1/tr1/unordered_map:63: создается из Б─≤std: : tr1 :: unordered_map, std :: equal_to, std :: allocator>, false>, std :: tr1 :: hash, std :: equal_to, std :: allocator, std :: equal_to, std :: allocator>, false >>>, false> Б─≥
test.cpp: 42: создается здесь
/usr/lib/gcc/x86_64-redhat-linux/4.1.1/../../../../include/c++/4.1.1/tr1/hashtable:863: ошибка: Б─≤Internal: : hash_code_base :: m_h1Б─≥ имеет неполный тип
/usr/lib/gcc/x86_64-redhat-linux/4.1.1/../../../../include/c++/4.1.1/tr1/functional:1101: ошибка: объявление Б─≤ struct std :: tr1 :: hashБ─≥

test.cpp: 42: создается здесь
является

YY::TTXM m;

Если я изменю

typedef std::tr1::unordered_map<XTE, TXM> TTXM;

в

typedef std::tr1::unordered_map<XTE, TXM*> TTXM;

он успешно компилируется, но я не хочу этого делать.
Есть идеи, предложения, как заставить это работать?

1

Решение

Он жалуется, что не имеет хэш-функции для long longтак что просто добавь

_my_tr1_hashtable_define_trivial_hash(long long);

и тебе должно быть хорошо идти.


Постскриптум Я думаю, что причина использования TXM * вместо TXM работает потому, что компилятору не нужно разрешать тип TXM, если он является указателем, поэтому он не идет по пути выяснения, что у него нет всего должен создать этот тип .. а именно длинную длинную хеш-функцию. Если бы вы позже попытались создать экземпляр объекта TXM, он бы потом пожаловался вам на ошибку, аналогичную той, что вы видите сейчас.

3

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

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

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