C++中是否有类似于Scala的mixin机制?

21
3个回答

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>);
}

坦白说,我还没有通过编译测试过这个代码,但你应该能够理解它的意思。

3

Scala的一些mixin特性可以使用多重(虚拟)继承来实现。但遗憾的是,这往往会引入更多问题而不是解决问题。此外,你不能像下面这样即兴混合匹配超类:

val me = new Human with Coder with Musician

如果你真的、真的想要真正的mixin,几乎必须采用像@Logan Capaldo所提出的模板解决方案。


3

再次强调并扩展之前电子邮件中提到的内容,让我首先举一个例子,说明如何在C++中实现Scala Ordered trait,然后让我展示如何在实例化时混合任意数量的“traits”。

首先让我们从Ordered trait开始。如果您熟悉Scala SDK,则会注意到有一个Ordered trait。这用于通过实现简单的“compare”方法来提供完全排序。在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);
};

显然,您可以混合使用尽可能多的“traits”,但如果您以这种方式操作,则无法在实例化时添加或删除“traits”。是否有简单的解决方案?有点。

听说过C++0x可变模板吗?这提供了一种在模板实例化时混合使用尽可能多的“traits”的方法。

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

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

这里的问题是什么呢?问题在于无法像这样做:

。涉及到IT技术相关内容。
template <typename... MIXINS>
class Host : public MIXINS<HOST>... {
    // Your implementation
};

在某些情况下,这可能很方便。

无论如何,C++具有一些基本机制,可以模拟Scala的Mix-ins的某些方面。但它无法实现堆叠行为。

希望对你有所帮助。


“然而,它无法实现的是堆叠行为”。也许我错了,但是通过模板参数使mixin彼此派生,最终从混合类派生,不就可以简单地实现堆叠行为吗? - Fabio A.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接