开发者

Using a mixin (?) to make stream i/o easier

Since many students I work with on common code have some problems comprehending proper stream operator overloading, I tried to create a helper template (don't know if this is a real mixin) to facilitate the code and insure correct operator implementation. Here it comes:

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

Inheriting class:

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

The downsides of this implementation as far as I see them at the moment:

  • Does not work for 3rd party types
  • Includes inheritance and thus tight coupling with the IoClass although not every user might need Io for a certain type

The ups:

  • It works ;-)
  • Similar stream classes can be added without modifying all classes and withou writing specific new code for every class

Since I'm not very experienced in the usage of mixins and tend to violate coding guidelines once in a while, I'd like to know if this is an appropriate usage of 开发者_高级运维a mixin or how one could obtain a similar effect with another more suitable technique.

Many Thanks, Martin


If they can write scan and print template functions, they might as well write templated operators directly, skipping this entire silly mixin business.

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

Also, that special-cased QDebug overload looks entirely unnecessary and wrong.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜