2015-12-06 3 views
0

У меня проблема преобразования этого куска кода в г ++ от MSVC:Явная специализация шаблона в г ++, вызывая неприятность

#include <unordered_map> 
class A 
{ 
    template <class T> class B; 

    template<> 
    class A::B<int> 
    { 

    }; 

    std::unordered_map<int, long, B<int>> m_Map; 
}; 

Sure вещи это не стандарт C++, в то время как VS еще это позволяет GCC (г ++) выдает ошибку «Явная специализация в области без пространства имен». Теперь я делаю это C++ совместимый следующие ссылки http://en.cppreference.com/w/cpp/language/template_specialization:

#include <unordered_map> 

class A 
{ 
    template <class T> class B; 
    template <> class B<int>; 
    std::unordered_map<int, long, B<int>> m_Map; 
}; 

template<> 
class A::B<int> 
{ 
    std::size_t operator()(int const& n) const { 
    } 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    A a; 
    return 0; 
} 

Увы, теперь VS дает мне ошибку

Error 3 error C2079: 'std::_Hash_oper1<true,_Hasher>::_Hashobj' uses undefined class 'A::B<int>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xhash 

и

Error 2 error C2139: 'A::B<int>' : an undefined class is not allowed as an argument to compiler intrinsic type trait '__is_empty' c:\program files (x86)\microsoft visual studio 12.0\vc\include\type_traits 

Таким образом, неупорядоченная карта определенно не хочет работать с тем, что он считает «неопределенным классом». Даже несмотря на то, что я нападал, - заявил он. Кто-нибудь знает, что это такое? Спасибо.

+1

Простое исправление было бы сделать класс 'B' не объявляется в' Ā' в первую очередь –

+0

Спасибо , это работает, вы можете опубликовать в качестве ответа. – southerton

ответ

1

Контейнеры стандартной библиотеки не могут быть объявлены неполными типами в качестве содержащихся в них типов. Это приводит к неопределенному поведению без необходимости диагностики (что означает, что некоторые компиляторы могут его принять, а некоторые могут отклонить его или вести себя странно во время выполнения).

Вам понадобится использовать хеш-таблицу из другой библиотеки (например, Boost), которая поддерживает неполный тип или перепроектирует код.

Простое исправление было бы сделать класс B не быть объявлен в A в первую очередь

+0

Я думаю, что вряд ли существует реализация, которая поддерживает неполные * хэширования *. –

+0

Они используют неполный тип 'B ' как третий параметр шаблона - хешер. Это понятно, потому что реализация почти наверняка сохранит хешер напрямую (вероятно, завернутый в некоторые механизмы, обеспечивающие EBO). –

+0

@ T.C. О, я неправильно прочитал ваш комментарий. Не обращай на меня внимания :) –

Смежные вопросы