使用 mixin (?) 使流 I/O 更容易
由于与我一起处理通用代码的许多学生在理解正确的流运算符重载方面存在一些问题,因此我尝试创建一个帮助器模板(不知道这是否是真正的 mixin)来简化代码并确保正确的运算符实现。它来了:
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;
}
}
据我目前所见,此实现的缺点:
- 不适用于第 3 方类型
- 包含继承,因此与 IoClass 紧密耦合,尽管并非每个用户都需要 Io 对于某种类型
ups:
- 它有效;-)
- 可以添加类似的流类,而无需修改所有类,也无需为每个类编写特定的新代码,
因为我在 mixin 的使用方面不是很有经验,并且往往违反编码准则有时,我想知道这是否是 mixin 的适当用法,或者如何使用另一种更合适的技术获得类似的效果。
非常感谢,马丁
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果他们可以编写
scan
和print
模板函数,他们也可以直接编写模板化运算符,从而跳过整个愚蠢的 mixin 业务。此外,特殊情况下的 QDebug 重载看起来完全没有必要而且是错误的。
If they can write
scan
andprint
template functions, they might as well write templated operators directly, skipping this entire silly mixin business.Also, that special-cased QDebug overload looks entirely unnecessary and wrong.