Подтвердить что ты не робот

Существуют ли scala -подобные mixins для С++?

Scala Mixins

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

val me = new Human with Coder with Musician

Если вы действительно хотите действительно настоящих миксинов, вам почти нужно пойти с чем-то вроде решения шаблона, предложенного в ответ, Logan Capaldo.

Ответ 3

Чтобы повторить и расширить то, что упоминалось в предыдущих письмах, позвольте мне сначала привести пример реализации Scala Упорядоченный признак на С++, а затем дать мне возможность показать, как вы можете смешивать произвольное количество "признаков", во время создания экземпляра.

Начнем сначала с символа "Заказ". Если вы знакомы с SDK Scala, вы заметите, что есть атрибут Ordered. Это используется для обеспечения полного упорядочения с помощью простого метода сравнения. В С++ вы можете сделать то же самое:

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

Затем, чтобы присвоить свойство упорядочения классу С++, вы можете сделать следующее:

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

Очевидно, вы можете смешивать столько "признаков", сколько хотите, но если вы сделаете так, вы не сможете добавлять или удалять черты во время создания экземпляра. Есть ли простое решение для этого? Вид-оф.

Вы слышали о вариативных шаблонах С++ 0x? Это обеспечивает способ смешивания как можно большего количества признаков во время создания шаблона.

Трюк прост, просто объявите свой хост-класс следующим образом:

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

Какая уловка здесь? Ну, проблема в том, что невозможно сделать что-то вроде этого:

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

Что в некоторых случаях было бы удобно.

В любом случае С++ имеет некоторый базовый механизм, который позволяет эмулировать некоторые аспекты Scala Mix-ins. Однако это не может быть поведение стекирования.

НТН.