【问题标题】:Initializing a static templated member of a template class初始化模板类的静态模板成员
【发布时间】:2013-02-13 21:37:37
【问题描述】:

我有以下代码sn-p,但它不起作用。 dataMap 成员应该包含一个回调函数,该函数接受一个 T& 和 T 在适当的时间传递给回调。模板成员初始化失败(使用 g++ 4.7.2):error: need ‘typename’ before ‘MyClass<T>::DataMap’ because ‘MyClass<T>’ is a dependent scope。我尝试将 typename 粘贴在它所说的位置,但随后出现了另一个错误:error: expected primary-expression before ‘;’ token。 是否可以这样做,或者我是否需要从初始化中删除 typedef?我试着沿着那条路走,但它很快就变得难以辨认并且吐出了更多错误。

template <typename T> class MyClass
{
public:
  typedef void(*CallbackType)(T&);
  typedef std::unordered_map<int, std::pair<T, CallbackType>/**/> DataMap;
  static DataMap dataMap;
  ...
};

template <typename T> MyClass<T>::DataMap MyClass<T>::dataMap = MyClass<T>::DataMap;

【问题讨论】:

  • 您是否尝试在 MyClassDataMap 的两次出现之前放入“typename”?
  • 这两个我都试过了:template &lt;typename T&gt; typename MyClass&lt;T&gt;::DataMap MyClass&lt;T&gt;::dataMap = MyClass&lt;T&gt;::DataMap;template &lt;typename T&gt; typename MyClass&lt;T&gt;::DataMap MyClass&lt;T&gt;::dataMap = typename MyClass&lt;T&gt;::DataMap; 都失败了。
  • @kwiqsilver:第一个 typename 是必须的,第二个不是;但如果您使用复制初始化,则需要在DataMap 之后使用括号(())。请参阅下面的答案。

标签: c++ templates static-members


【解决方案1】:

编译器正确地建议您可能需要包含typename 关键字,因为DataMapMyClass&lt;T&gt;::DataMap 中的限定依赖 名称。静态成员定义应如下所示:

template <typename T>
typename MyClass<T>::DataMap MyClass<T>::dataMap;

该成员将被默认构造,因此无需复制初始化。因此,省略= MyClass&lt;T&gt;::DataMap 部分就足够了(这会给您带来麻烦,因为您忘记了复制初始化右侧DataMap 之后的括号):

// This is also valid (mind the parentheses to invoke the
// constructor of `DataMap`), but unnecessary.
template <typename T>
typename MyClass<T>::DataMap MyClass<T>::dataMap = MyClass<T>::DataMap();

【讨论】:

  • 在 = 符号后不需要'typename' 吗?
  • @bstamour:可以使用,但不是必须的。
  • 类似于我假设的继承列表中不需要它。在这种情况下,它只能是一种类型,因此没有歧义。
猜你喜欢
  • 1970-01-01
  • 2016-03-10
  • 1970-01-01
  • 2011-03-14
  • 2021-10-21
  • 2019-05-03
  • 2011-01-21
  • 2011-01-19
相关资源
最近更新 更多