如何以通用方式打印任何容器的内容?
我正在尝试使用 C++ 模板编写一段有趣的代码。
#include <iostream>
#include <vector>
template <class Container>
std::ostream& operator<<(std::ostream& o, const Container& container)
{
typename Container::const_iterator beg = container.begin();
o << "["; // 1
while(beg != container.end())
{
o << " " << *beg++; // 2
}
o << " ]"; // 3
return o;
}
int main()
{
std::vector<int> list;
list.push_back(0);
list.push_back(0);
std::cout << list;
return 0;
}
上面的代码无法编译:)
在 1、2、3 处会产生相同的错误:错误 C2593: 'operator <<' 是不明确的
我想做的就是重载 << 操作员可以使用任何容器。 那有意义吗 ? 如果可以的话,该怎么做,如果不能的话,为什么?
编辑::感谢您的更正:)“某种”方式是一个很好的解决方案。
我只是好奇如果我们可以使用 C++0x Concepts,这种歧义(正如 Neil 所解释的)是否会消失?
I am trying to write a piece of code for fun using C++ templates.
#include <iostream>
#include <vector>
template <class Container>
std::ostream& operator<<(std::ostream& o, const Container& container)
{
typename Container::const_iterator beg = container.begin();
o << "["; // 1
while(beg != container.end())
{
o << " " << *beg++; // 2
}
o << " ]"; // 3
return o;
}
int main()
{
std::vector<int> list;
list.push_back(0);
list.push_back(0);
std::cout << list;
return 0;
}
The above code doesn't compile :)
At 1, 2, 3 the same error is produced : error C2593: 'operator <<' is ambiguous
All what I am trying to do is overloading the << operator to work with any container. Does that make sense ? How would that be done If possible, if not why ?
EDIT :: Thanks for corrections :) 'sth' way is a good solution.
I am just curious if this ambiguity -as Neil explained- would go away if we could use C++0x Concepts ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您可以限制您的运营商<< 通过指定 Container 模板参数本身是模板化的,仅适用于模板化容器。 由于 C++ std 容器也有一个分配器模板参数,因此您还必须将其包含为 Container 的模板参数。
You can restrict your operator<< to only apply to templated containers by specifying that the Container template parameter is itself templated. Since the C++ std containers also have an allocator template parameter you also have to include this as a template parameter of Container.
新定义的
运算符<<
不仅匹配容器,还匹配任何其他类型,例如整数和字符串。 这就是为什么编译器在需要找到匹配的运算符<<
来输出“[”
时会抱怨歧义。解决此问题的一种方法是重命名输出函数:
然后,您可以添加简单的包装器,为所有要打印的容器启用
operator<<
:Your newly defined
operator<<
does not only match containers, but also any other types like ints and strings. That's why the compiler complains about ambiguities when it needs to find the matchingoperator<<
to output"["
.One way to work around this problem would be to rename your output function:
You can then add simple wrappers to enable
operator<<
for all the containers you want to print:错误是什么? 我看到一个,你需要一个类型名:
这里发生的情况是,编译器在第一次读取 Container 时对它一无所知。 因此,我们必须给它一点帮助,并告诉它迭代器将是一个类型(从语法上讲,它可以是类范围内的任何有效名称,例如函数、变量……)。 在编写模板方法时,任何依赖于模板类型的类型都必须指定它是带有关键字
typename
的类型。What is the error? I saw one, you need a typename:
What happens here is that the compiler doesn't know anything about Container when it is first reading it. So we have to give it a little help and tell it that iterator will be a type(syntactically it could be any valid name at class scope, so a function, variable,...). When writing a template method, any type that depends on the template type must specify that it is a type with the keyword
typename
.您的操作员引入了自己的歧义 - 它本身可以用于打印它试图打印的内容。 我的建议:
Your operator introduces its own ambiguity - it could itself be used for printing the things it is trying to print. My advice:
好的,现在你的模板引起了混乱。 编译器无法在您的运算符和您期望的运算符之间做出决定。
Ok, now your template it causing confusion. The compiler can't decide between your operator and the one that you would expect.
也许不像您发布的内容那么通用(您需要传递包含的类型),并且还在末尾留下额外的分隔符,但您可以使用 STL 来实现这一点:
将输出:
请注意,额外的分隔符位于序列的末尾,并且 [ 和第一个元素之间没有初始空格。
Maybe not as generic as what you are posting (you need to pass the type contained), and also leaves an extra separator at the end, but you can use the STL for this:
Will output:
Note that the extra separator is at the end of the sequence and that there is no initial space between the [ and the first element.
http://blog.csdn.net/cqdjyy01234/article/details/19234329可能是一个很好的解决方案。 它适用于 STL 容器和 C 样式数组。
http://blog.csdn.net/cqdjyy01234/article/details/19234329 may be a good solution. It works for STL containers and the C-style array.
您可以使用constexpr检查不同打印机制的容器(例如Stacks,Queues)的数据类型,并添加名为PrintContainer的通用方法,请检查以下代码。
首先检查堆栈、队列、映射等数据类型。
然后包括像这样的打印容器的通用方法。
然后像这样从 Main 方法调用它。
输出:
完整源代码 - PrintContainer.cpp
You can use constexpr to check Datatype of containers like Stacks,Queues for different printing mechanism and add generic method called PrintContainer check the below code.
First check datatype for Stack,Queue,Map etc.
Then include General method for Printing Container like this.
Then call it from Main method like this.
Output:
Full Source Code - PrintContainer.cpp