【问题标题】:Unresolved external symbol for type traits template class类型特征模板类的未解析外部符号
【发布时间】:2016-11-17 11:20:36
【问题描述】:

我有以下代码用于实现Tag Dispatching

template <class T> struct tag
{
    typedef struct {} type;
   static const type value;
};

然后我在几个定义中使用这个结构来提供函数的重载版本,由于某种原因,这些函数可能是模棱两可的。例如,我有一组 unarchive 函数,它们采用单个参数 unarchiver ar。后面的类型使用类型特征来决定要使用的重载版本,从而确定要取消归档的类型。这是一个取消归档数据包的示例:

packet HYP_NAMESPACE unarchive(unarchiver ar, typename tag<packet>::type)
{
    // Code here
}

可以这样调用:

unarchive(ar, tag<packet>::value);

此代码适用于 gcc 和 clang,但在 VS 2015 中失败。我只是收到一堆错误,例如:

LNK2001 未解析的外部符号“public: static struct tag::type const tag::value”(?value@?$tag@G@@2Utype@12@B)

struct tag 声明位于其自己的标头 (.h) 中,其用法出现在整个实现 (.cpp) 文件中。谁能确定造成这种情况的原因?

【问题讨论】:

  • 你在哪里明确定义你的静态成员变量?
  • 嗯.. 没想到。我不。在这种情况下,我不需要初始化的特定值,如果它包含垃圾应该没问题。您认为这是导致错误的原因吗?

标签: c++ c++11 templates visual-studio-2015 typetraits


【解决方案1】:

这:static const type value; 是静态成员变量value 的声明,它承诺该变量将在其他地方定义。

这:template &lt;class T&gt; const typename tag&lt;T&gt;::type tag&lt;T&gt;::value; 是一个定义。

定义不仅仅是初始化。

【讨论】:

  • 谢谢乔纳斯。事实上,我不记得初始化变量。有趣的是,它如何与 clang 和 gcc(我的初始目标)一起工作,这让我相信一切都很好。
  • 是的,两种编译器在很多情况下都会接受没有定义的静态成员变量。但是,正如您所注意到的,它不是很便携。
  • 知道了!我通常只使用 gcc 和 clang,所以这让我想知道。现在已经修好了。
  • 我一直觉得很奇怪的是,你甚至可以在没有定义的情况下初始化静态成员变量,然后使用它们,一切正常,直到你通过引用传递它们(它们变成“ODR used ) 然后您没有定义的事实会导致链接器错误。似乎最好限制更多。
猜你喜欢
  • 1970-01-01
  • 2011-08-12
  • 1970-01-01
  • 2020-03-08
  • 2013-05-25
  • 2013-12-18
  • 2012-04-23
  • 2014-04-03
  • 1970-01-01
相关资源
最近更新 更多