bay*_*yda 16 c++ stl namespaces operator-overloading
我有下一个代码:
#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, "\n" ) );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这段代码中我只想要复制映射到输出流.为此,我需要定义operator <<(..) - OK.但根据名称查找规则编译器找不到我的运算符<<().
因为std :: cout,std :: pair和std :: copy调用了我的运算符<< - all from namespace std.
快速解决方案 - 将我的oerator <<添加到std命名空间 - 但它很难看,imho.
您知道这个问题的解决方案或解决方法吗?
Mic*_*fik 16
cout a没有标准的方法,std::pair因为,你想要它的打印方式可能与下一个人想要它的方式不同.这是自定义函子或lambda函数的一个很好的用例.然后,您可以将其作为参数传递std::for_each给工作.
typedef std::map<size_t, size_t> MyMap;
template <class T>
struct PrintMyMap : public std::unary_function<T, void>
{
std::ostream& os;
PrintMyMap(std::ostream& strm) : os(strm) {}
void operator()(const T& elem) const
{
os << elem.first << ", " << elem.second << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
要从您的代码中调用此仿函数:
std::for_each(some_map.begin(),
some_map.end(),
PrintMyMap<MyMap::value_type>(std::cout));
Run Code Online (Sandbox Code Playgroud)
bay*_*yda 14
我已经找到了一种解决这个问题的新方法.
阅读答案时,我有很多有趣的想法:
我想我将来会用这些想法来解决其他不同的问题.
但是对于这种情况,我已经明白我可以将我的问题表述为"将地图的数据转换为字符串并将其写入输出流"而不是"将地图的数据复制到输出流".我的解决方案如下:
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, "\n" ),
toString );
Run Code Online (Sandbox Code Playgroud)
我认为这种方法比其他方法更短,更具表现力.
你想要的是一个转换迭代器.这种迭代器包装另一个迭代器,转发所有定位方法,如operator ++和operator ==,但重新定义operator*和operator->.
快速草图:
template <typename ITER>
struct transformingIterator : private ITER {
transformingIterator(ITER const& base) : ITER(base) {}
transformingIterator& operator++() { ITER::operator++(); return *this; }
std::string operator*() const
{
ITER::value_type const& v = ITER::operator*();
return "[" + v->first +", " + v->second + "]";
}
...
Run Code Online (Sandbox Code Playgroud)