【问题标题】:C++: Pure virtual typeC++:纯虚类型
【发布时间】:2013-03-04 19:36:30
【问题描述】:

我正在探索 C++ (C++11) 中的模板恶作剧,我想要的一件事是抽象类中的纯虚拟类型。这就像 Scala 的abstract types。在 C++ 中,我想做如下的事情:

struct Base {
  // Says any concrete subclass must define Type, but doesn't
  // require that it be anything in particular.
  virtual typedef MyType; 
};

struct Derived : Base {
  // Won't compile unless this typedef exists.
  typedef int MyType;
};

知道怎么做吗?

【问题讨论】:

  • 你为什么需要这个?
  • 你要这个干什么?知道你的目标肯定会让你更好地得到答案。不,“模拟一些随机的 Scala 特性”不算作目标。
  • @Xeo - 海报是“探索模板恶作剧” - 这是一个人为的目标,但仍然是一个目标! :)
  • 我正在用 C++ 实现类型类。 (我知道这之前已经做过了,但我没有找到什么是我想要的。)特别是,如果我想编写一个支持映射的通用类型类,我需要像 Scala 的 CanBuildFrom (scala-lang.org/api/current/…) .很好地做到这一点似乎需要虚拟类型。

标签: c++ scala templates generic-programming


【解决方案1】:

我不确定 C++ 是否真的需要这个。

试图让自己处于寻找这种解决方案的设计师的位置,我会说需要这种约束来强制某些类型遵守某些语法约定。

这很可能是必需的,因为通用算法需要语法约定:它不能与未定义此类类型关联的类型一起使用。

例如,下面的算法要求其参数的类型具有关联的bar_type

template<typename T>
bool foo(T t)
{
    typedef typename T::bar_type FT;
    FT ft;
    ...
}

但如果是这种情况,则无需强制typedef 来有效地限制foo&lt;&gt;() 的输入:简单地省略bar_type 的类型定义不会使可以将该类型与foo&lt;&gt;() 一起使用。

当然,只有在您真正尝试这样做时,您才会发现这一点,而不是在此之前。并且能够定义一个概念,例如HasBarType,然后强制一些类型来实现这个概念会很好;另一方面,概念不是 C++ 的一部分,尽管它们是可取的,但没有它们也是可能的。

【讨论】:

  • 如果您希望能够使现有的第 3 方或原始类型满足您的要求,还有 my_tag_type&lt;T&gt;::bar_type。见std::iterator_traits&lt;int*&gt;::value_type
  • @MooingDuck:是的,这是执行它的另一种方式
  • @AndyProwl,你在概念上一针见血;如果没有正确实现类型类(基本上是概念,据我所知),我会尝试强制早期编译失败。
  • @emchristiansen:那么我不确定这对于“一劳永逸”的声明/断言是否可行。在 C++ 中,我相信您仍然必须为每种类型明确指定一个声明/断言:它可能在这些类型之外 ,但我会说它必须存在。
【解决方案2】:

编辑

这不起作用,但我认为curiously recurring template pattern 可能是要走的路。

/编辑

template<typename Dependent>
class Base : public Dependent {
    typedef typename Dependent::MyType MyType;
};

然后使用curiously recurring template pattern:

struct Derived : Base<Derived> {
  // Won't compile unless this typedef exists.
  typedef int MyType;
};

【讨论】:

  • Have you tried compiling that?顺便说一句,缺少typename :-)
  • @PeterWood,我尝试使用 CRTP 通常解决这个问题,但没有成功。明显的问题:CRTP 将 Base 的依赖添加到 Derived,当 Derived 对 Base 有依赖时,你会得到一个无限的模板循环。
猜你喜欢
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 2011-03-20
  • 1970-01-01
  • 2011-09-08
  • 1970-01-01
  • 1970-01-01
  • 2018-05-02
相关资源
最近更新 更多