用于从std :: vector(或其他序列)读取的流语法?

时间:2011-06-29 18:27:44

标签: c++ templates stream

想象一下,我有一个Variant类,可以表示各种POD类型,加上std :: string,我有一个模板方法T get_value(const Variant&),可以从中提取基础类型。

假设我有这些的矢量,即。 std::vector<Variant> variants;,我想用方便的语法从中读取几个值,如下所示:

int x;
double y;
std::string z;
// Get elements 0, 1, and 2 as int, double, and string respectively
streamlikeObject >> x >> y >> z;

问题是:在示例中形成假设streamlikeObject的好方法是什么?我可以想象用一个提取运算符创建我自己的类,但我只是对std库中是否存在某些东西感兴趣,或者可能是Boost处理这类事情。

或者替代方案:如何以相似程度的代码简洁性提取这些数据?也许有更好的流语法替代方案。

4 个答案:

答案 0 :(得分:3)

类似(未经测试的

template <typename Iter>
class Extractor {
    Iter cur;
    Iter const &end;

  public:
    Extractor(Iter const &begin, Iter const &end)
      : cur(begin), end(end) { }

    template <typename T>
    Extractor &operator>>(T &x)
    {
        if (cur == end)
            throw SomeException();
        x = cur->get_value();
        ++cur;
        return *this;
    }
};

使用Extractor<std::vector<Variant>::const_iterator> streamlikeObject(v.begin(), v.end());构建。

或者,如果您只想从容器中提取,则可能需要在容器类型而不是迭代器类型上对模板进行参数化以节省输入(pardon pun)。

答案 1 :(得分:1)

所以,让我确保我理解正确。

你有一个std :: vector,它包含任意数据。其内容是运行时定义的。

并且您希望获取此运行时定义的对象并在其上应用编译时序列,如下所示:

std::vector<Variant> >> val1 >> val2 >> val3;

我认为如果当前值与预期类型不匹配,您的代码将抛出,是吗?

你可以使用一些Boost.IOStream的设施。您基本上会创建一个使用您的变体而不是char的新流类型。你需要一个流缓冲区,它从(可能是const)引用中提取到这些Variant个对象的容器。

答案 2 :(得分:0)

这样的事情:

struct A
{
  int a;
  float b;
  std::string c;
};

std::istream& operator>>( std::istream &is, const A &a )
{
  is >> a.a;
  is >> a.b;
  is >> a.c;
  return is;
}

答案 3 :(得分:0)

如果目标是创建通用的东西,我可能会尝试使用std::tuple,允许这样使用:

std::tuple<int, double, std::string> input;
streamLikeObject >> input;

(实施留给读者练习。)