【问题标题】:C++: Enforcing template type implements a methodC++:强制模板类型实现方法
【发布时间】:2012-10-17 11:49:19
【问题描述】:

我有一个模板类,我想知道是否可以强制模板类类型实现某个接口,特别是我想强制该类型重载operator= 方法。在 Java 中我会写:

public class Tree<T implements IComparable>{
    public Tree(Vector<T> x){...}
}

C++ 中的替代方案是什么?

【问题讨论】:

标签: c++ templates interface


【解决方案1】:

假设它可以编写代码。如果没有,当用户传入不符合的类型时,它将无法编译。这里不需要明确的特征。但是到底为什么你需要一个像 IComparable 这样的接口呢?模板是鸭子类型的。

但是模板错误可能会变得很糟糕。您可以使用类型特征和静态断言来简化此操作。但是,标准没有提供这样的特征,因此您必须使用 SFINAE 编写一个。

【讨论】:

  • 不完全正确。只有在使用该功能时才会编译失败。例如,我可以使用Tree&lt;int&gt;,即使它没有实现 ICompareable,它也可能仍然可以编译。或者我可以使用Tree&lt;PLOP&gt;,其中 PLOP 没有实现 ICompareable 但由于某种原因我的代码没有插入任何成员(例如不完整的测试套件)。
  • @LokiAstari:有人可能会说 DeadMG 暗示了 Just write the code assuming that it does
  • @phresnel:一个真实的例子:您可能希望强制标准向量中的类型是可复制的。否则某些事情会刹车。但是你可以做std::vector&lt;auto_ptr&lt;int&gt; &gt; x;,如果你不让内部结构重新调整大小,它不会破坏(即使在测试中)。所以很有可能有从根本上被破坏的代码(但似乎工作)。我认为问题的精神是我们希望它总是在编译时中断。如果我们使用某些特性,在编译时不会中断。
  • 如果您从不调用该函数,那么您就不需要它,对吗?
  • @DeadMG:非常正确。但这是一个不同的问题。问题是如何强制模板参数实现接口。这样做是有充分理由的(假设您不能在一天内编写整个应用程序)。
【解决方案2】:

简答:

没有;没有语言功能可以做到这一点。

Shotish 答案:

可以使用SFINAE 和静态断言(在编译时评估的断言)来实现您想要的效果。不幸的是,这是一个不平凡的过程,需要对模板元编程有很好的理解。

冗长的答案:

为新的 C++11 标准建议了这些功能,但没有通过审核过程。在此处阅读更多信息http://en.wikipedia.org/wiki/Concepts_(C%2B%2B)。在当前会议(波特兰 10 月 12 日至 19 日)上,Herb Sutter 建议我们应该尝试分两个阶段发布(一个小版本,然后是一个新功能版本),并且概念将包含在第一个小版本中。该提案是否被接受,将在会后公布。

【讨论】:

  • @LokiAstari:因为在 C++03 和 C++11 中,可以(并且现在)检查模板参数是否具有特定的运算符重载,或者它是否派生自特定接口,并导致硬编译错误(通过静态断言)或软 SFINAE 错误。概念(尽管不同的人并没有就他们应该是什么样子达成一致)只是试图使人们已经在做的事情成为“官方方式”,例如。在特征类的帮助下。
猜你喜欢
  • 1970-01-01
  • 2019-07-09
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 2010-12-18
  • 2015-10-27
  • 2021-01-21
  • 1970-01-01
相关资源
最近更新 更多