我正在努力加快“现代”C ++的速度,特别是使用模板。我有一个类覆盖了<<<<<<<运营商。工作良好。所以我决定为容器添加漂亮的打印件。
我的问题 - 有没有办法为多个容器类型编写模板,类似于下面的代码?
template <typename T>
std::ostream& operator <<(ostream& os, const vector<T>& v)
{
os << "\n";
for( auto x : v ) { os << "\n\t" << x; }
os << "\n";
return os;
}
上述代码正确地以多行格式输出向量,只要T具有&lt;&lt;运营商。我想让其他容器如列表等工作。
我也意识到,对于所有类型,以一般方式覆盖容器的输出可能是一个坏主意(或者至少是粗鲁的)。因此,上面的模板代码最终会将typename硬编码/限制为'Point'和模板化容器。
好的,恭维AndyG的建议我有以下完整代码:
#include <iostream>
#include <map>
#include <vector>
using namespace std;
struct Point {
double x, y, z;
Point() : x(0), y(0), z(0) {};
Point(double a, double b, double c) : x(a), y(b), z(c) {}
Point(double a[]) : x(a[0]), y(a[0]), z(a[0]) {}
friend std::ostream& operator <<(ostream& os, const Point&p)
{
os << p.x << ", " << p.y << ", "<< p.z;
return os;
}
};
template <template<class> class C, class... T>
std::ostream& operator <<(ostream& os, const C<T...>& v)
{
os << "\n";
for( auto x : v ) { os << "\n\t" << x; }
os << "\n";
return os;
}
vector<Point> vp = { { 1, 2, 3 },
{ 5, 7, 4 },
{ 8, 2, 5 }
};
int main(int argc, char* argv[])
{
cout << vp[0]; // works
cout << vp; // dosen't work,
}
但仍然没有运气。编译器无法匹配运算符&lt;&lt;用'std :: vector'
我在第一篇文章之前尝试过很多template <template>
的变体,结果大致相同。我可以得到一个编译的模板,但编译器无法匹配运算符函数并使用模板。
我不知道可变参数模板包,显然是一个好主意,但没有解决问题。
答案 0 :(得分:0)
好的,AndyG让我走上正轨,我想我明白发生了什么。
以下代码不起作用,因为std :: container模板也有一个具有默认值的allocator参数,您很少需要使用它。因此,我们认为大多数容器模板只采用它们将包含的类型/类。
此
template < template <class> class C, class... T>
std::ostream& operator <<(ostream& os, const C<T...>& v)
{ ... }
不起作用,因为我们要在我们的运算符中调用C
的模板&lt;&lt;函数有两个参数而不是一个。因此,编译器无法找到匹配项。
这将有效:
template < template <class, class> class C, class... T>
std::ostream& operator <<(ostream& os, const C<T...>& v)
因为编译器可以将vector<Point, Alloc>
与我们选择调用template<class, class>
的{{1}}进行匹配。然后,它可以使用我们的函数模板为C
生成重载。
请注意,此方法通常存在许多问题。 operator <<
不匹配std :: map,它带有4个参数,其中2个是默认值。更糟糕的是,将匹配任何两个参数模板,这些模板可能是也可能不是容器。
我们可以通过使用varg参数来解决这个问题:template <class, class>
但是我们仍然搞砸了,因为现在&lt;&lt;函数模板处理来自迭代器的template <class, class...>
,编译器不知道如何std::pairs
。
因此,尽管这对我来说更好地理解模板是一种有用的练习,但不要这样做。
此链接有一个整洁的容器漂亮的打印lib:Pretty-print C++ STL containers