【问题标题】:Stream syntax for reading from std::vector (or other sequence)?从 std::vector (或其他序列)读取的流语法?
【发布时间】:2011-09-25 09:51:09
【问题描述】:

假设我有一个 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 感兴趣。

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

【问题讨论】:

  • 重载全局运算符<template T> streamlikeObject & operator<<(streamlikeOperator & s, T & t)怎么样?
  • 问题是 streamlikeObject 不存在。 :)

标签: c++ templates stream


【解决方案1】:

类似(未经测试

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&lt;std::vector&lt;Variant&gt;::const_iterator&gt; streamlikeObject(v.begin(), v.end());构造。

或者,如果您只想从容器中提取,您可能希望在容器类型而不是迭代器类型上参数化模板以节省输入(请原谅双关语)。

【讨论】:

  • 我希望我能做的最好的事情是编写一个适配器,它接受一个容器并包装其中一个提取器。
【解决方案2】:

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

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

而您想要获取这个运行时定义的对象并对其应用编译时序列,如下所示:

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

我想如果当前值与预期类型不匹配,你的代码就会抛出,是吗?

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

【讨论】:

    【解决方案3】:

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

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

    (实现留给读者作为练习。)

    【讨论】:

      【解决方案4】:

      类似这样的:

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

      【讨论】:

      • "顺便说一句,std::string 不是 POD" - 我认为这很明显,通过我提出问题的方式。
      • @Kylotan 对,我会编辑我的答案,但我不太确定这是你想要的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-12
      • 1970-01-01
      • 2014-12-22
      • 1970-01-01
      相关资源
      最近更新 更多