打印对而不引入包装

时间:2016-04-01 16:31:47

标签: c++ stl

我知道我可以引入包装器(代理类)来包装对并添加重载<<运营商,但我想知道为什么要介绍'<<<&#像下面的std命名空间的运算符不起作用?

 #include <iostream>
 #include <iterator>
 #include <vector>
 #include <algorithm>

   namespace std{
    ostream& operator<<(ostream& os, pair<int, int>&);
   }

   std::ostream& std::operator<<(std::ostream& os, std::pair<int, int>& pi){
    os << pi.first <<", " << pi.second;
    return os;
   }

   int main(){
    std::vector< std::pair<int, int> > pi;
    pi.push_back(std::make_pair(1,2));
    std::cout << pi.front<<std::endl;
   }

2 个答案:

答案 0 :(得分:2)

这是非法的:

namespace std{
 ostream& operator<<(ostream& os, pair<int, int>&);
}

您可能只为std命名空间中的用户定义类型的函数专门化模板类。

您不能将用户定义类型的重载添加到std命名空间。

这是名称空间std中的重载。

预测:

  

但是正确的方法是什么?

这是:

#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>

template<class T>
struct tuple_printer;

template<class T>
auto tuple_print(const T& t) {
    return tuple_printer<std::decay_t<T>>(t);
}

template<class T>
struct tuple_printer
{
    tuple_printer(const T& t) : _t(t) {}

    void operator()(std::ostream& os) const {
        os << _t;
    }

    const T& _t;
};

template<class X, class Y>
struct tuple_printer<std::pair<X, Y>>
{
    using arg_type = std::pair<X, Y>;

    tuple_printer(const arg_type& t) : _t(t) {}

    void operator()(std::ostream& os) const {
        os << '(' << tuple_print(_t.first) << ", " << tuple_print(_t.second) << ')';
    }

    const arg_type& _t;
};

template<class T, class A>
struct tuple_printer<std::vector<T, A>>
{
    using arg_type = std::vector<T, A>;

    tuple_printer(const arg_type& t) : _t(t) {}

    void operator()(std::ostream& os) const {
        auto sep = " ";
        os << '[';
        for (const auto& e : _t) {
            os << sep << tuple_print(e);
            sep = ", ";
        }
        os << " ]";
    }

    const arg_type& _t;
};

template<class T>
std::ostream& operator<<(std::ostream& os, const tuple_printer<T>& tp){
    tp(os);
    return os;
}


int main(){
    std::vector< std::pair<int, int> > pi;
    pi.push_back(std::make_pair(1,2));
    pi.push_back(std::make_pair(3, 4));

    std::cout << tuple_print(pi.front()) << std::endl;
    std::cout << tuple_print(pi) << std::endl;

    return 0;
}

预期产出:

(1, 2)
[ (1, 2), (3, 4) ]

完美,嗯?

答案 1 :(得分:0)

您的代码中有一个简单的拼写错误:

std::vector< std::pair<int, int> > pi;
pi.push_back(std::make_pair(1,2));
std::cout << pi.front<<std::endl;

最后一行应为:

std::cout << pi.front() <<std::endl;

请注意std::pair<X,Y>::frontstd::vector<X>::front()之间的差异。

作为旁注,您应该让operator<<接受 const 对。