c++ - g++ 中的显式模板特化导致麻烦

标签 c++ c++11 gcc g++

我在将这段代码从 MSVC 转换为 g++ 时遇到了问题:

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

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

    };

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

当然这不是标准的 c++,而 VS 仍然允许它 GCC (g++) 抛出错误“非 namespace 范围内的显式特化”。现在我按照引用 http://en.cppreference.com/w/cpp/language/template_specialization 使它符合 C++ 标准。 :

#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

因此,无序映射绝对不想与它认为的“未定义类”一起工作。即使我转发声明它。 有谁知道这是怎么回事?谢谢。

最佳答案

标准库容器不能将不完整的类型声明为包含的类型。这会导致不需要诊断的未定义行为(意味着某些编译器可能会接受它,而某些编译器可能会拒绝它或在运行时表现异常)。

您将不得不使用来自支持不完整类型的不同库(例如 boost)的哈希表,或者重新设计代码。

一个简单的解决方法是让 B 类首先不在 A 中声明

关于c++ - g++ 中的显式模板特化导致麻烦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34122442/

相关文章:

c++ - 数组索引是否为 constexpr? GCC不一致?

带模板的 C++ 共享库 : Undefined symbols error

c++ - 对另一个静态库中的静态库方法的 undefined reference

c++ - Winsock 的 send() 工作异常

C++11: 'decltype class instance declaration' with std::move( ) 不调用 'move constructor.' 为什么?

c - gcc makefile 带有 -Wall -pedantic 和 -lpthread

c - mspgcc 中的意外结果

c++ - 将二维数组传递给 C++ 中的函数会出现以下错误

c++ - xutility(2227) : warning C4996: 'std::_Copy_impl'

c++ - 原子的 0 初始化是否保证将值成员设置为 0?