Вопрос

Это было полезно?

Решение

Нет, но его можно в разной степени подделать с помощью шаблонов:

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

Честно говоря, я не проверял это при компиляции, но вы должны уловить идею.

Другие советы

Некоторые аспекты миксинов Scala можно реализовать с помощью множественного (виртуального) наследования.К сожалению, это часто создает больше проблем, чем решает.Кроме того, вы не можете смешивать и сопоставлять суперклассы на лету. а-ля:

val me = new Human with Coder with Musician

Если ты действительно, Действительно хотите настоящие миксины, вам почти придется использовать что-то вроде шаблонного решения, предложенного в ответе @Логан Капальдо.

Чтобы повторить и расширить то, что упоминалось в предыдущих письмах, позвольте мне сначала дать вам пример того, как реализовать признак Scala Ordered в C++, а затем позвольте мне показать, как вы можете смешивать произвольное количество «типов» во время создания экземпляра.

Начнем с черты Ordered.Если вы знакомы с 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.Однако он не может складывать поведение.

ХТХ.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top