我有一个与({C ++ 11版本的)std::ostream
非常相似的类,我可以流式传输许多不同的(不相关的)类型。
class mystream{...some implementation...};
要定义的典型功能是
mystream& operator<<(mystream& ms, type1 const& t1){...}
mystream& operator<<(mystream& ms, type2 const& t2){...}
等
然而,(就像使用C ++ 11&#9的流一样)我想在流程上进行构建。例如:
mystream{} << t1;
为了能够做到这一点,我为每种类型的l值引用重载:
mystream& operator<<(mystream&& ms, type1 const& t1){
return ms << t1; // this calls the l-value version
}
代码并不复杂,但它是重复的,因为我必须为所涉及的所有类型执行此操作。由于此类的性质,使用引用和l值引用是有意义的。
问题是这是否是正确的做法?我应该为每种类型写两个函数吗?这是一个好模式吗?
次要问题:当然,我可以在适当的时候做一些模板魔术来接受l值参考,但我不知道这是否是推荐路径。
三元问题:函数应该返回mystream&
(如上所述)还是mystream&&
。
这是示例代码:
class A{};
class B{};
class mystream{};
mystream& operator<<(mystream& ms, A const& a){return ms;} // (1)
mystream& operator<<(mystream& ms, B const& b){return ms;} // (2)
mystream& operator<<(mystream&& ms, A const& a){return ms; /*ms << a;*/} // (3)
mystream& operator<<(mystream&& ms, B const& b){return ms; /*ms << a;*/} // (4)
int main(){
mystream ms;
ms << A{};
ms << B{};
mystream{} << A{}; // ok only if line (3) is defined
mystream{} << B{}; // ok only if line (4) is defined
}
如果我对第(3)行进行注释,则错误信息为
fatal error: invalid operands to binary expression ('mystream' and 'A')
mystream{} << A{}; // ok only if line (3) is defined
~~~~~~~~~~ ^ ~~~
././random.hpp:146:11: note: candidate function not viable: expects an l-value for 1st argument
mystream& operator<<(mystream& ms, A const& a){return ms;} // (1)
如果我评论第(1)行,则反过来
fatal error: invalid operands to binary expression ('mystream' and 'A')
ms << A{};
~~ ^ ~~~
././random.hpp:149:11: note: candidate function not viable: no known conversion from 'mystream' to 'mystream &&' for 1st argument
mystream& operator<<(mystream&& ms, A const& a){return ms; /*ms << a;*/} // (3)
答案 0 :(得分:2)
C ++定义了一个带有ostream右值引用的函数模板:
template< class CharT, class Traits, class T >
basic_ostream< CharT, Traits >& operator<<( basic_ostream<CharT,Traits>&& os,
const T& value );
它调用适当的插入运算符。因此,您应该只定义
template <typename X>
mystream& operator<< (mystream&& ms, const X& x)
{
ms << x;
return ms;
}