C ++有scala-like mixins吗?

时间:2009-02-03 01:05:07

标签: c++ scala traits mixins template-mixins

3 个答案:

答案 0 :(得分:14)

不,但可以使用模板进行不同程度的伪造:

template<typename AbsIterator> 
class RichIterator : public AbsIterator {
public:
   template<typename FuncType>
   void foreach(FuncType f) { while( hasNext() ) f( next() ); }
};

class StringIterator {
  std::string m_s;
  int i;
public:
  typedef char T;
  StringIterator() : m_s(), i(0) {} // Unfortunately need this, or 
                                    // else RichIterator
                                    // gets way more complicated
  StringIterator(const std::string &s) : m_s(s), i(0) {}
  void swap(StringIterator& other) {
     m_s.swap(other.m_s);
     std::swap(i, other.i);
  }
  void reset_str(const std::string& s) {
     StringIterator(s).swap(*this);
  }
  bool hasNext() { return i < m_s.length(); }
  char next() { return m_s[i++]; }
};

template<typename Outputable>
void println(const Outputable& o) {
   std::cout << o << std::endl;
}

int main(int argc, char **argv) {
  typedef RichIterator<StringIterator> Iter;
  Iter iter;
  iter.reset_str(argv[1]);
  iter.foreach(&println<Iter::T>);
}

说实话,我还没有通过编译对它进行测试,但你应该明白这一点。

答案 1 :(得分:3)

使用多个(虚拟)继承可以满足Scala mixins的某些方面。不幸的是,这通常会引入比解决的问题更多的问题。此外,您无法动态混合和匹配超类 a la

val me = new Human with Coder with Musician

如果你真的,真的想要真正的mixins,你几乎不得不像@ Logan Capaldo那样使用回答中提出的模板解决方案。

答案 2 :(得分:3)

重申并扩展之前电子邮件中提到的内容让我首先举例说明如何在C ++中实现Scala Ordered特性,然后让我展示如何在实例化中混合使用任意数量的“特征”时间。

让我们先从Ordered trait开始。如果您熟悉Scala SDK,您会注意到有一个Ordered特征。这用于通过实现简单的“比较”方法来提供总排序。在C ++中,您可以执行以下操作:

template <typename T>
class Ordered {
public:
    virtual int32_t compare(const T& that) = 0;
    bool operator >(const T& that) {return this->compare(that) == 1; }
    bool operator >=(const T& that) {return this->compare(that) >= 0; }

    bool operator ==(const T& that) { return this->compare(that) == 0; }

    bool operator <=(const T& that) {return this->compare(that) <= 0; }
    bool operator <(const T& that) {return this->compare(that) == -1; }
};

然后,为了给C ++类提供排序属性,您可以执行以下操作:

class MyOrderedType : public Ordered<MyOrderedType> {
public:
  // Your ctor/dtors, methods
public:
  int compare(const MyOrderedType& that);
};

显然,您可以根据需要混入任意数量的“特征”,但如果您这样做,则无法在实例化时添加或删除特征。有一个简单的解决方案吗?样-的。

听说过C ++ 0x可变参数模板吗?这提供了一种在模板实例化时混合所需数量的特征的方法。

诀窍很简单,只需按如下方式声明主机类:

template <typename... MIXINS>
class Host : public MIXINS... {
 // Your implementation
};

这里的问题是什么?嗯,问题是不可能做这样的事情:

template <typename... MIXINS>
class Host : public MIXINS<HOST>... {
    // Your implementation
};

在某些情况下哪些方便。

在任何情况下,C ++都有一些基本机制,允许您模拟Scala混音的某些方面。然而,不能做的是堆叠行为。

HTH。