我想定义运算符<<以类似于STL算法的方式操作一系列元素,通过将容器的第一个和最后一个元素作为参数。与仅采用一个参数相反,容器本身,例如
std::ostream& operator<< ( std::ostream &out, std::list inList );
因此,我只需编写一个无论是否使用list,vector,array等都可以工作的函数。我必须使用两个参数inList.begin()和inList调用该函数。端()
问题是运营商&lt;&lt;只需要一个参数。克服这个问题的最佳方法是什么?
编辑:谢谢你的回答。我应该更清楚地表明我更愿意能够打印一系列元素,包括可能是容器的子序列(再次,像STL算法)。例如。如果一个向量v有5个元素,我希望可以打印它们所有给出一个从v.begin()到v.end()的序列,输出如下:[element1 element2 element3 element4 element5]
但是我希望我也能打印前三个,在[v.begin(),v.begin()+ 3)范围内
[element1 element2 element3]
在这种情况下,您建议的答案是否有效?
答案 0 :(得分:2)
你无法摆脱传递一个论点,但你希望某些容器可以使用。理想情况下,你会想要一个像
这样的函数template <typename T>
std::ostream& someFunction(std::ostream& out, T first, T last) {
// do your stuff
}
和ostream& operator<<
正在寻找 之类的
template <T>
std::ostream& << (std::ostream& out, const T& sequence) {
return someFunction(out, sequence.begin(), sequence.end());
}
但是,此运算符将与预定义运算符冲突,因此您不能像这样实现它。幸运的是,您可以玩一些模板魔术来解决这个问题,并且看到一个非常好的解决方案,请查看this SO question和相应的github project
请注意,由于(可能)目标是为容器设置通用ostream& operator<<
,并且您可以通过函数模板实现此目的,因此使函数采用迭代器并不是必需的。它也可以对容器进行(const)引用。
答案 1 :(得分:1)
只传递一个参数,并在方法内部使用begin
和end
。所有标准容器都有begin
和end
。不,您不能将参数数量更改为operator <<
。
答案 2 :(得分:1)
这是一个老问题,但我最近必须解决同样的问题,所以我想在这里发布我的解决方案。 Range和makeRange复制了std :: pair和std :: make_pair的功能,但我添加了前者只是为了避免冲突(其他类型的对可能会以不同的方式打印)。
#include <iostream>
using namespace std;
template <typename Iterator>
struct Range
{
Range();
Range(Iterator begin_, Iterator end_) : begin(begin_), end(end_) {}
Iterator begin, end;
};
template <typename Iterator>
Range<Iterator>
makeRange(Iterator begin, Iterator end)
{
return Range<Iterator>(begin, end);
}
template <typename InputIterator>
ostream &
operator<<(ostream & out, Range<InputIterator> const & range)
{
for (InputIterator iter = range.begin; iter != range.end; ++iter)
{
if (iter != range.begin) out << ", "; // adjust formatting to taste
out << *iter;
}
return out;
}
int
main(int argc, char * argv[])
{
int a[] = { 1, 2, 3, 4, 5 };
cout << makeRange(a, a + 2) << endl; // prints 1, 2
}