0

我想定义运算符 << 以对一系列元素进行操作,就像 STL 算法一样,将容器的第一个和最后一个元素作为参数。与仅采用一个参数相反,容器本身,例如

std::ostream& operator<< ( std::ostream &out, std::list inList );

所以我只需要编写一个函数,不管我是否使用列表、向量、数组等,我都必须使用两个参数调用该函数,inList.begin() 和 inList.end()

问题是 operator<< 只接受一个参数。克服这个问题的最佳方法是什么?

编辑:谢谢你的回答。我可能应该更清楚地表明我希望能够打印一系列元素,可能包括容器的子序列(再次,如 STL 算法)。例如,如果一个向量 v 有 5 个元素,我希望可以将它们全部打印出来,给出一个从 v.begin() 到 v.end() 的序列,输出如下:

[element1 element2 element3 element4 element5]

但我希望我也可以只打印前三个,在 [v.begin(), v.begin()+3) 范围内

[element1 element2 element3]

您建议的答案在这种情况下有效吗?

4

3 回答 3

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());
}

但是,此运算符会与预定义的运算符发生冲突,因此您不能就这样实现它。幸运的是,您可以玩一些模板魔术来解决这个问题,并看到一个非常好的解决方案,查看这个 SO question和相应的github 项目

请注意,由于(可能)目标是ostream& operator<<为容器提供泛型,并且您可以通过函数模板来实现这一点,因此函数采用迭代器并不是必需的。它也可以对容器进行 (const) 引用。

于 2012-06-01T14:40:06.307 回答
1

只传递一个参数,并在方法内部取beginend。所有 std 容器都有beginend。不,您不能将参数的数量更改为operator <<.

于 2012-06-01T14:31:38.510 回答
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
}
于 2016-04-26T04:33:47.740 回答