Използване на mixin (?) за улесняване на потока I/O

Тъй като много студенти, с които работя върху общ код, имат някои проблеми с разбирането на правилното претоварване на оператора на потока, опитах се да създам помощен шаблон (не знам дали това е истински миксин), за да улесня кода и да осигуря правилното внедряване на оператора. Задава се:

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, въпреки че не всеки потребител може да се нуждае от Io за определен тип

Прозорците:

  • Работи ;-)
  • Подобни класове на потока могат да се добавят, без да се променят всички класове и без да се пише специфичен нов код за всеки клас

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

Много благодаря, Мартин


person Martin    schedule 12.10.2011    source източник


Отговори (1)


Ако могат да напишат 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 със специален случай изглежда напълно ненужно и погрешно.

person Cat Plus Plus    schedule 12.10.2011
comment
IMHO: Напълно шаблонни оператори на потоци, като предлаганите от вас, могат да ви създадат големи проблеми, както ми беше казано преди време и също имах опит stackoverflow.com/questions/4195764/. - person Martin; 12.10.2011
comment
Освен това QDebug е доста удобен за използване за отстраняване на грешки (без chache, червен цвят, всички QT DataTypes вече се поддържат ...). За съжаление не може да се претовари с нормалния синтаксис. За да напишете qDebug() ‹‹, както е предложено в qt framework, трябва да следвате пътя, предложен в doc.qt.nokia.com/latest/qdebug.html. - person Martin; 12.10.2011
comment
Също така за вашите шаблони все още ще трябва да се обаждате на аксесоари или да ги правите приятели. - person Martin; 12.10.2011