std::copy 到 std::cout 用于 std::pair

2022-01-14 00:00:00 namespaces operator-overloading c++ stl

我有下一个代码:

#include <iostream>
#include <algorithm>
#include <map>
#include <iterator>

//namespace std
//{

std::ostream& operator << ( std::ostream& out, 
                const std::pair< size_t, size_t >& rhs )
{
    out << rhs.first << ", " << rhs.second;
    return out;
}
//}

int main() 
{

    std::map < size_t, size_t > some_map;

    // fill  some_map with random values
    for ( size_t i = 0; i < 10; ++i )
    {
        some_map[ rand() % 10 ] = rand() % 100;
    }

    // now I want to output this map
    std::copy( 
        some_map.begin(), 
        some_map.end(), 
        std::ostream_iterator< 
              std::pair< size_t, size_t > >( std::cout, "
" ) );

    return 0;
}

在这段代码中,我只想将地图复制到输出流.为此,我需要定义运算符 <<(..) - 好的.但是根据名称查找规则编译器找不到我的运算符<<().
因为 std::cout、std::pair 和 std::copy 调用了我的操作符<<- 全部来自命名空间 std.

In this code I just want copy map to output stream. For do this I need define operator <<(..) - OK. But according names finding rules compiler can't find my operator<<().
Because std::cout, std::pair and std::copy which called my operator<< - all from namespace std.

快速解决方案 - 添加我的运营商

到 std 命名空间 - 但它很丑,恕我直言.

Quick solution - add my oerator<< to std namespace - but it is ugly, imho.

您知道什么解决方案或解决方法?

What solutions or workaround for this problem do you know?

推荐答案

我已经建立了一种新的优雅方法来解决这个问题.
阅读答案时,我有很多有趣的想法:

I've founded one new elegant way to solve this problem.
I've got many interest ideas when read answers:

  • 包装迭代器,用于将 std::pair 转换为 std::string;
  • 包装 std::pair,以便有机会重载运算符<<(...);
  • 将通常的 std::for_each 与打印函子一起使用;
  • 使用 std::for_each 和 boost::labda - 看起来不错,除了访问 std::pair<>::first 和 std::pair<>::第二个成员;

我想我将来会使用所有这些想法来解决其他不同的问题.
但是对于这种情况,我理解我可以将我的问题表述为将地图的数据转换为字符串并将它们写入输出流"而不是将地图的数据复制到输出流".我的解决方案如下:

I think I will use all of this ideas in future for solve different other problems.
But for this case I've understaded that I can formulate my bproblem as "transform map's data to strings and write them to output stream" instead "copy map's data to ouput stream". My solution looks like:

namespace
{
std::string toString( const std::pair< size_t, size_t >& data)
{
    std::ostringstream str;
    str << data.first << ", " << data.second;
    return str.str();
}
} // namespace anonymous

std::transform( 
    some_map.begin(), 
    some_map.end(), 
    std::ostream_iterator< std::string >( std::cout, "
" ),
    toString );

我认为这种方法比其他方法最简短,最具表现力.

I think this method is most short and expressive than others.

相关文章