我编写了元组实现,这似乎有效:
template<typename T, typename... U>
struct tuple{
T first;
tuple<U...> second;
tuple()=default;
tuple(T t, U... u):first(t), second(u...){}
std::ostream& print(std::ostream& stream){
stream<<first<<", ";
return second.print(stream); //not using << to avoid extra () in output
}
};
template<typename T>
struct tuple<T>{
T first;
tuple()=default;
tuple(T t):first(t){}
operator T&(){
return first;
}
std::ostream& print(std::ostream& stream){
return stream<<first;
}
};
template<typename... T>
inline auto mk_tuple(T... t){
return tuple<T...>(t...);
}
我有operator<<
这样重载:
template<typename... T>
std::ostream& operator<<(std::ostream &stream, tuple<T...> &out){
stream<<'(';
return out.print(stream)<<')';
}
当我尝试以这种方式使用它时:std::cout<<mk_tuple(1, 2, 3, "xyz", 'c');
我明白
error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
但是,mk_tuple(1, 2, 3, "xyz", 'c').print(std::cout)
有效。
(但这并不令人满意,因为它在 C++ 中不是明显的语法)。
我应该如何重载operator<<
在这种情况下能够正确使用它吗?
最佳答案
签名错误,您需要:
template<typename... T>
std::ostream& operator<<(std::ostream &stream, const tuple<T...> &out){
// ^^^^^
因为您不会修改输出上的元组
。然后,这允许使用常量或临时值调用您的运算符。
它还要求您将 print
方法标记为 const
:
std::ostream& print(std::ostream& stream) const {
// ^^^^^
一般来说,谷歌搜索“const Correctness”并了解 C++ 中的这一基本范例。
编辑:明白了!试试这个签名:
template<typename T, typename... U>
std::ostream& operator<<(std::ostream &stream, const tuple<T, U...> &out){
stream<<'(';
return out.print(stream)<<")";
}
因为一些旧版本的 GCC 似乎有一个错误,导致它们无法正确推导 T...
。
关于c++ - 无法使用重载运算符<<来打印对象的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26076067/