Использование mixin (?) Для облегчения потокового ввода-вывода - PullRequest
3 голосов
/ 12 октября 2011

Поскольку у многих студентов, с которыми я работаю над общим кодом, есть некоторые проблемы с пониманием правильной перегрузки оператора потока, я попытался создать вспомогательный шаблон (не знаю, является ли это реальным миксином), чтобы упростить код и обеспечить правильную реализацию оператора. Вот оно:

template<typename T> struct IoEnabled {
  friend std::ostream& operator<<(std::ostream& out, T const& val) {
    return val.print(out);
  }

  friend std::istream& operator>>(std::istream& in, T& val) {
    return val.scan(in);
  }

  friend QTextStream& operator<<(QTextStream& out, T const& val) {
    return val.print(out);
  }

  friend QTextStream& operator>>(QTextStream& in, T& val) {
    return val.scan(in);
  }

  friend QDebug operator<<(QDebug dbg,T const& val){
    std::stringstream myStream;
    myStream << val;
    dbg.nospace() << myStream.str().c_str();
    return dbg;
  }
};

Класс наследования:

class Foo: private IoEnabled<Foo> {
  protected:
   int mData;

  public:
    template<typename U>
    U& scan(U& in) {
      in >> mData;
      return in;
    }

    template<typename U>
    U& print(U& out) const {
      out << mData;
      return out;
    }
}

Недостатки этой реализации, насколько я вижу их на данный момент:

  • Не работает для сторонних типов
  • Включает наследование и, следовательно, тесную связь с IoClass, хотя не каждому пользователю может понадобиться Ио для определенного типа

Взлеты:

  • Работает; -)
  • Подобные потоковые классы могут быть добавлены без изменения всех классов и без написания нового кода для каждого класса

Поскольку я не очень опытен в использовании миксинов и склонен время от времени нарушать правила кодирования, я хотел бы знать, является ли это подходящим использованием миксина или как можно получить подобный эффект с другая более подходящая техника.

Большое спасибо, Мартин

1 Ответ

2 голосов
/ 12 октября 2011

Если они могут писать шаблонные функции scan и print, они также могут писать шаблонные операторы напрямую, пропуская весь этот глупый смешанный бизнес.

struct Foo {
    int mData;
    Foo() : mData(mData) {}
};

template <typename OutputStream>
OutputStream& operator<<(OutputStream& stream, const Foo& data) {
    stream << data.mData;
    return stream;
}

template <typename InputStream>
InputStream& operator>>(InputStream& stream, Foo& data) {
    stream >> data.mData;
    return stream;
}

Кроме того, эта специальная перегрузка QDebugвыглядит совершенно ненужным и неправильным.

...