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

发布于 2024-11-17 15:58:48 字数 550 浏览 1 评论 0 原文

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

假设我有一个向量,即。 std::vector<变体>变体;,我想用方便的语法从中读取几个值,如下所示:

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 中是否有处理此类事情的东西感兴趣。

或者:还有什么其他方法可以以类似的代码简洁程度提取这些数据?也许有更好的流语法替代方案。

Imagine I have a Variant class which can represent a variety of POD types, plus std::string, and I have a template method T get_value(const Variant&) that can extract the underlying types from it.

Assume I have a vector of these, ie. std::vector<Variant> variants;, and I want to read several values from it with a convenient syntax, like so:

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

The question is: what is a good way to form the hypothetical streamlikeObject in the example? I can imagine creating my own class with an extraction operator but I am just interested as to whether there's something in the std library or maybe Boost which handles this sort of thing.

Or alternatively: how else can this data be extracted with a similar degree of code brevity? Maybe there is a better alternative to the stream syntax.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不爱素颜 2024-11-24 15:58:48

类似(未经测试

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::const_iterator> 构造的东西StreamlikeObject(v.begin(), v.end());

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

Something like (untested)

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

Construct with Extractor<std::vector<Variant>::const_iterator> streamlikeObject(v.begin(), v.end());.

Alternatively, if you only want to extract from containers, you may want to parametrize the template on the container type instead of the iterator type to save typing (pardon pun).

庆幸我还是我 2024-11-24 15:58:48

所以让我确保我正确理解这一点。

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

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

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

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

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

So let me make sure I understand this correctly.

You have a std::vector, and it contains arbitrary data. The contents of which are runtime-defined.

And you want to take this runtime-defined object and apply a compile-time sequence on it like this:

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

I suppose your code will just throw if the current value doesn't match the expected type, yes?

You could use some of Boost.IOStream's facilities for this. You would basically be making a new stream type that uses your Variants instead of char. And you would need a stream buffer that pulls from a (presumably const) reference to a container of these Variant objects.

冰雪之触 2024-11-24 15:58:48

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

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

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

If the goal is to create something generic, I'd probably try something with std::tuple, allowing usage like this:

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

(Implementation left as an exercise for the reader.)

¢蛋碎的人ぎ生 2024-11-24 15:58:48

像这样的东西:

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

Something like this :

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文