我编写了元组实现,这似乎有效:
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<<
才能正确使用它?
答案 0 :(得分:3)
签名错误,您需要:
template<typename... T>
std::ostream& operator<<(std::ostream &stream, const tuple<T...> &out){
// ^^^^^
因为您不打算修改输出中的tuple
。然后,这允许使用常量或临时值调用操作符。
还要求您将print
方法标记为const
:
std::ostream& print(std::ostream& stream) const {
// ^^^^^
一般来说,google&#34; const correctness&#34;并在C ++中学习这个基本范例。
template<typename T, typename... U>
std::ostream& operator<<(std::ostream &stream, const tuple<T, U...> &out){
stream<<'(';
return out.print(stream)<<")";
}
因为某些旧版本的GCC似乎有一个错误,导致他们无法正确推断T...
。