如何实现读取二进制到变量的istream操纵符int32_le_read
实现
int32_le_read二进制输入操纵符的解决方案 问题描述
我想要实现一个int32_le_read(x)操纵符,用于从文件读取二进制数据并写入到x中。我已实现了int32_bin_manip类:
class bin_manip { public: bin_manip(); ~bin_manip(); friend std::istream& operator>>(std::istream& is,bin_manip& obj); friend std::ostream& operator<<(std::ostream& os, const bin_manip& obj); virtual std::ostream& write(std::ostream& os) const = 0; virtual std::istream& read(std::istream& is) = 0; }; class int32_bin_manip : public bin_manip { public: int32_t* x; int32_bin_manip(int& x); std::ostream& write(std::ostream& os) const; std::istream& read(std::istream& is); };
该类已存在对应的operator>>和operator<<运算符。目前我已成功实现ostream操纵符:通过创建返回类实例的函数write_le_int32即可正常使用:
int32_bin_manip write_le_int32(int& x) { return int32_bin_manip(x); }
但无法用同样方式实现istream操纵符,因为operator>>的参数是int32_bin_manip& obj(非const引用),若创建返回类实例的函数并以istream >> int32_le_read(x)的方式使用,会将临时实例绑定到非const引用,这是C++所禁止的。
可行解决方案
1. 为bin_manip添加右值引用版本的operator>>
C++11及以后支持右值引用,可以直接重载operator>>以接受临时对象:
// 在bin_manip类中添加友元声明 friend std::istream& operator>>(std::istream& is, bin_manip&& obj); // 类外实现 std::istream& operator>>(std::istream& is, bin_manip&& obj) { return obj.read(is); }
之后就可以用和ostream操纵符完全一致的方式实现int32_le_read:
int32_bin_manip int32_le_read(int& x) { return int32_bin_manip(x); }
使用时is >> int32_le_read(x);即可正常编译,因为右值引用允许绑定临时对象。
2. 使用代理类中转
如果无法修改原有的bin_manip类,可以创建一个代理类来完成操作:
// 定义代理类 struct int32_le_read_proxy { int& target; explicit int32_le_read_proxy(int& x) : target(x) {} }; // 为代理类实现输入运算符 std::istream& operator>>(std::istream& is, int32_le_read_proxy proxy) { int32_bin_manip manip(proxy.target); return manip.read(is); } // 操纵符函数 int32_le_read_proxy int32_le_read(int& x) { return int32_le_read_proxy(x); }
这种方式不需要改动原有类结构,通过代理对象将读取操作中转给已实现的int32_bin_manip。
3. 将operator>>的参数改为值传递
虽然会产生一次对象拷贝,但也是简单有效的方案:
// 修改bin_manip类中的友元声明 friend std::istream& operator>>(std::istream& is, bin_manip obj); // 类外实现 std::istream& operator>>(std::istream& is, bin_manip obj) { return obj.read(is); }
临时对象会被拷贝到函数参数中,调用read方法完成数据读取,同样可以复用原有的操纵符函数实现方式。
内容的提问来源于stack exchange,提问作者Max Nov
相关产品推荐
相关产品推荐

