【发布时间】:2013-09-12 13:28:54
【问题描述】:
以下代码是我在 C++11 中第一次尝试漂亮地打印可迭代容器。它使用函数模板默认参数特性。
#include <ostream>
#include <string>
#include <utility>
template <typename T>
void print(std::ostream &o, T const &t) { o<< t; }
void print(std::ostream &o, std::string const &s){ o<< '"'<< s<< '"'; }
template <typename K, typename V>
void print(std::ostream &o, std::pair<K, V> const &p)
{
o<< '{'; print(o, p.first);
o<< ": "; print(o, p.second);
o<< '}';
}
template <typename C, typename I= typename C::const_iterator>
std::ostream &operator<< (std::ostream &o, C const &c)
{
o<< '[';
if(c.empty()) return o<< ']';
I b= c.begin(), e= c.end(); -- e;
for(; b!= e; ++ b)
{
print(o, *b);
o<< ", ";
}
print(o, *b);
return o<< ']';
}
它适用于容器、容器容器等。除了一个例外:
std::cout<< std::string("wtf");
使用 g++4.7/8 编译会中断 ambiguous operator<<。
是否有任何修复此代码以避免歧义?
【问题讨论】:
-
因为
std::string有一个const_iterator,所以你的operator<<模板是匹配的。 -
@VaughnCato 是的,如果可能的话,我希望 std::basic_string
重载是首选。 -
当
C是一个字符串时,您可以使用enable_if来禁用您的重载。 -
OT,但您可以使用
auto b = c.begin()而不是I b
标签: templates c++11 operator-overloading pretty-print iterable