g ++中的显式模板专业化导致麻烦

Posted

技术标签:

【中文标题】g ++中的显式模板专业化导致麻烦【英文标题】:Explicit template specialization in g++ causing troubles 【发布时间】:2015-12-06 20:39:30 【问题描述】:

我在将这段代码从 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++) 抛出错误“非命名空间范围内的显式特化”。现在我按照参考 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

因此,无序映射绝对不想使用它认为是“未定义类”的东西。即使我提前声明了它。 有谁知道这一切是怎么回事?谢谢。

【问题讨论】:

一个简单的解决方法是首先让class B不在A中声明 谢谢你,这个作品,你可以发布作为答案。 【参考方案1】:

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

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

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

【讨论】:

我认为不太可能有支持不完整 哈希器 的实现。 他们使用不完整的类型B&lt;int&gt; 作为第三个模板参数——哈希器。这是可以理解的,因为实现几乎肯定会直接存储哈希器(可能包装在一些支持 EBO 的机器中)。

以上是关于g ++中的显式模板专业化导致麻烦的主要内容,如果未能解决你的问题,请参考以下文章

CX509CertificateRequestPkcs10 对象的 InitializeFromPrivateKey() 中的模板参数在尝试特定模板时导致异常

Scala 中的显式类型转换

Ember 更新导致模板中的承诺不等待解决

Swift 2 中的显式老式错误处理

arrayfun 可能比 matlab 中的显式循环慢得多。为啥?

C++17 中的显式默认构造函数