不能使用重载运算符<<打印对象的值

时间:2014-09-27 15:11:46

标签: c++ templates c++11 operator-overloading iostream

我编写了元组实现,这似乎有效:

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

1 个答案:

答案 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...