如何重载 >> 运算符以接受可变参数列表

3
我是一位有用的助手,可以为您翻译文本。

我希望你能重载一个“>>”运算符,使得任何人都可以输入任意数量的值。

这是我正在处理的任务要求:

运算符“>>”应该期望看到以下形式的输入:d v1 v2 ... vd,其中d是向量的维度,每个vi是向量中索引i对应的值。

我认为它的工作方式应该是第一个值将是数组的大小(包含在对象Vex中),其余的将是元素。因此,如果他们输入

Vex vX;
4, 1, 2, 3, 4 >> vX; 

vX会创建一个大小为4的动态数组,其中包含数字1-4。

我卡在如何编程>>重载上,因为参数数量是可变的。

理想情况下,我希望有一个类似以下示例的解决方案:

std::istream& Vex::operator>>(istream& is, const Vex&){
   /*
     Assume int * data has been previously declared in constructor
     data = new int[iterator[0]]
     create iterator of input for istream
     For n from 1 to iterator[0]...
         data[n] = iterator[n] 
   */
}

我不知道具体该怎么做。我已经找到了istream_iterator,但是没有找到有人使用它的好例子来满足我的需求。

希望我提供的信息足以回答问题。如果不够,请告诉我。

非常感谢您的时间。


1
你不能这样做。有其他方式可以实现同样方便的结果,例如 vX = {1,2,3,4};但如果你非要用这种特定语法,那么就没有办法了。 - Benjamin Lindley
为了确保我表述清楚,我将逐字逐句地复制我的编程作业要求:“Operator>> 应该期望看到以下形式的输入:d v1 v2 … vd,其中 d 是向量的维度,每个 vi 是向量中索引 i 对应的值。” - SemperCallide
2
你应该向你的老师询问以获得澄清,但我非常确定 d v1 v2 ... vd 是指运行时的用户输入,而不是源代码。 - Benjamin Lindley
这是非惯用语。">>" 是提取运算符,但您正在将其用作插入运算符。 - Raymond Chen
4个回答

9

你的老师并不要求你重载 operator>> 以接受可变参数列表。他要求你这样重载 operator>> :在运行时以特定方式解析用户(或文件,或任何 istream 对象)提供的可变长度输入。你需要的函数声明如下:

std::istream& operator>>(istream& is, Vex& v)

这个函数不应该是一个成员函数,但你可能需要它成为友元函数。

我不了解这个 Vex 类,所以无法告诉你如何编写该函数,但大致上会像这样:

read an integer N from the stream
set size of Vex object as N, however that's done
for i = 1 to N
    read number X from the stream
    store X in Vex object at position i

你的意思是“将X存储在Vex对象中的位置i吗?” - Code-Apprentice

0

记住逗号是一个运算符。它会评估每个表达式并返回右操作数的值。此外,它从左到右关联。最后,>>的优先级高于,。这意味着

4, 1, 2, 3, 4 >> vX;

等同于

((((4, 1), 2), 3), (4 >> vX));

但是4, 1的值为1,因此上述代码的结果为:
(((1, 2), 3), (4 >> vX));

它的计算结果为

((2, 3), (4 >> vX));

这将被评估为

(3, (4 >> vX));

求值为

4 >> vX;

为了使上述语句编译通过,您必须进行重载。
Vex& operator>>(int, Vex&);

从你最初的问题的评论中可以看出,教授希望您为您的Vex类重载operator>>。这意味着签名应该是:

istream& operator>>(istream&, Vex&);

1
不,>> 的优先级比,更高,无论它是否被重载,因此 4, 1, 2, 3, 4 >> vX 等同于 4, 1, 2, 3, (4 >> vX)(这又等同于 (4 >> vX),因为字面量没有副作用且其值被丢弃)。 - Keith Thompson

0
你想太多了。仔细阅读规范。我认为以下内容非常接近要求。
GCC 4.7.3:g++ -Wall -Wextra -std=c++0x
#include <vector>
#include <iostream>
#include <string>
#include <sstream>

template <class T>
struct Vex {
  std::vector<T> v;
};

template <class T>
std::istream& operator>>(std::istream& is, Vex<T>& vex) {
  auto dim = 0;
  is >> dim;
  for (auto i = 0; i < dim; ++i) {
    T t;
    is >> t;
    vex.v.push_back(t);
  }
  return is;
}

int main() {
  std::stringstream is("4 1 2 3 4");
  Vex<int> vex;
  is >> vex;

  for (auto i : vex.v) {
    std::cout << i << " ";
  }

  return 0;
}

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接