【问题标题】:typedef throwing error even with typename keyword即使使用 typename 关键字,typedef 也会抛出错误
【发布时间】:2016-10-08 07:14:52
【问题描述】:

以下 C++ 代码:

template<typename State>
class Node
{
public:
    typedef typename State::Move Move;
...
}

说:

缺少类型说明符 - 假定为 int。注意:C++ 不支持 default-int

我搜索了错误消息,每个人都建议将 typename 关键字添加到 typedef 行,在我的情况下已经存在。我还能做什么?

【问题讨论】:

  • 你确定这是错误所在吗?
  • @tkausl:至少在双击消息时会将我带到这一行。
  • 为我编译:cpp.sh/2lqe5
  • 10.7k 代表并且没有 MCVE?
  • 代码过多并不是不创建 MCVE 的借口。删除代码,直到错误消失。最后删除的代码可能与错误有关,因此将其放回原处。继续,直到您有可能实际证明您的问题的最小示例。在创建 MCVE 的过程中,您可能会有“啊哈!”时刻,并意识到问题所在。否则,人们将有机会帮助您....您发布的问题并非如此。

标签: c++ typedef


【解决方案1】:

感谢所有帮助过的人。问题确实出在其他地方。让我解释一下:

在 C# 中,我们在类定义中使用泛型(大致相当于 C++ 模板系统)并可以对它们应用约束:

class Node<T> where T:SomeClass { ... }

它允许我们在这个类中实例化T 类型的对象。这些对象将自动拥有SomeClass 的所有成员。你也会得到很好的智能感知作为奖励。这个系统的好处是可以在编译时验证这个类的完整性,而无需实例化 Node&lt;T&gt; 类型的对象。

[免责声明:以下是我的理解。如果我错了,请纠正我。]

C++ 不能以这种方式工作。 C++ 将允许您根据模板参数访问任何内容(在我的例子中是State::Move)。模板化类本身不能/不能确保模板参数实际上有一个名为Move 的成员。只有当你实例化一个模板类的对象时,例如Node&lt;SomeType&gt; x;,它实际上确保SomeType必须包含一个名为Move的成员,如果不是这样,就会抛出错误。

在我的问题中,我正在实例化Node 的对象并将int 作为模板参数传递给它,它显然没有任何名为Move 的成员,所以它在抱怨(不幸的是指向一个非常错误的地方,但那是另一个故事)。用适当的类型替换它为我修复了错误。

希望这对以后的人有所帮助。

【讨论】:

  • 如果你真的对 C++ 模板的潜在问题感兴趣,它的功能不是设计而是发现(原文如此!)远远超出“T 容器”,然后在 Google 中搜索“C++ 概念” .概念尚未成为 C++ 标准,但我想它们会使像这里的问题更容易检测和修复。
  • @ChristianHackl:请阅读 wiki 上的 C++ 概念主题。这似乎是 C# 泛型已经提供的东西。不?即参数约束、类型推导在 C#(和 VB.NET)中已经可用。还是不止这些?
  • 如果不是 C# 泛型方面的专家,我想说主要区别在于 C# 的泛型约束仅限于面向对象的范例。例如,对于您的where T:SomeClass,您实际上需要一个SomeClass 基类型,并且需要您的类型参数从它派生。对于概念或一般模板而言,情况并非如此。例如,可以使用一个概念明确声明某些模板函数 void f(T) 仅限于具有 foo 成员函数的 T,而无需 HasFooOperation 基类。
  • 进一步阅读:stackoverflow.com/questions/15634970/…。我特别喜欢这个总结:“主要区别在于模板定义了一个图灵完备的语言,在风格上是功能性的,尽管它的语法很糟糕,你可以在上面编程。”
猜你喜欢
  • 2011-05-24
  • 1970-01-01
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 2021-01-13
  • 2018-07-18
相关资源
最近更新 更多