2014-09-27 57 views
1

我写的元组执行,这似乎工作:不能使用重载运算符<<打印对象的价值

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<<才能正确使用它?

回答

2

签名是错误的,你需要:

template<typename... T> 
std::ostream& operator<<(std::ostream &stream, const tuple<T...> &out){ 
//            ^^^^^ 

,因为你不打算修改输出tuple。这样可以让您的操作员使用常量或临时值进行调用。

它也需要你来标记print方法const

std::ostream& print(std::ostream& stream) const { 
//          ^^^^^ 

一般情况下,谷歌“const正确性”,并了解在C++的这一重要范例。


编辑:明白了!试试这个签名:

template<typename T, typename... U> 
std::ostream& operator<<(std::ostream &stream, const tuple<T, U...> &out){ 
    stream<<'('; 
    return out.print(stream)<<")"; 
} 

一些旧版本的GCC似乎阻止他们正确地推断只是T...个错误。

+0

好点,但它们不会让代码编译。 – GingerPlusPlus 2014-09-27 15:23:41

+0

@GingerPlusPlus我无法读懂你的思想,所以你必须更具体:在修复操作符和**两个** print的签名之后,你得到的错误究竟是什么? – 2014-09-27 15:25:19

+0

'error:can not bind'std :: ostream {aka std :: basic_ostream }'lvalue to'std :: basic_ostream &&''and'/usr/include/c++/4.8/ostream:602:5:error:初始化'std :: basic_ostream <_CharT,_Traits>&std :: operator <<(std :: basic_ostream <_CharT,_Traits> &&,const _Tp&)的参数1 [with _CharT = char; _Traits = std :: char_traits ; _Tp =元组]''[我在线编译器中的整个代码](http://rextester.com/live/YZWQ61891) – GingerPlusPlus 2014-09-27 15:30:35