从istream读取boost :: variant类型 [英] Reading a boost::variant type from istream

查看:172
本文介绍了从istream读取boost :: variant类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过 boost :: variant ,想知道如何使以下工作?

I was going through boost::variant and wondering how can I make following to work ?

typedef boost::variant<int,std::string> myval;
int main()
{

std::vector<myval> vec;

std::ifstream fin("temp.txt");

//How following can be achieved ?
std::copy(std::istream_iterator<myval>(fin), //Can this be from std::cin too ?
          std::istream_iterator<myval>(),
          std::back_inserter(vec));   
}

对于类数据成员,我们可以选择重载 ;> 运算符,但是如何使用 myval 来执行此操作?

For classes data members we have option to overload >> operator, but how to do this with myval ?

推荐答案

您可以重载 operator>> c> variant ,就像任何其他类型。但是你需要实现逻辑来决定从流中读取什么类型并存储在 variant 中。下面是一个完整的例子:

You can overload operator>> for variant just like for any other type. But it is up to you to implement the logic to decide what type is read from the stream and stored in variant. Here's a complete example of how you might go about it:

#include "boost/variant.hpp"
#include <iostream>
#include <cctype>
#include <vector>
#include <string>

typedef boost::variant<int, std::string> myval;

namespace boost { // must be in boost namespace to be found by ADL
std::istream& operator>>(std::istream& in, myval& v)
{
    in >> std::ws;      // throw away leading whitespace
    int c = in.peek();
    if (c == EOF) return in;  // nothing to read, done

    // read int if there's a minus or a digit
    // TODO: handle the case where minus is not followed by a digit
    // because that's supposed to be an error or read as a string
    if (std::isdigit(static_cast<unsigned char>(c)) || c == '-') {
        int i;
        in >> i;
        v = i;
    } else {
        std::string s;
        in >> s;
        v = s;
    }
    return in;
}
} // namespace boost

// visitor to query the type of value
struct visitor : boost::static_visitor<std::string> {
    std::string operator()(const std::string&) const
    {
        return "string";
    }
    std::string operator()(int) const
    {
        return "int";
    }
};

int main()
{
    std::vector<myval> vec;
    std::copy(
        std::istream_iterator<myval>(std::cin),
        std::istream_iterator<myval>(),
        std::back_inserter(vec));

    std::cout << "Types read:\n";
    for (const auto& v : vec) {
        std::string s = boost::apply_visitor(visitor(), v);
        std::cout << s << '\n';
    }
}

输入示例: 1 2 3 hello 4 world

输出:

Types read:
int
int
int
string
int
string

这篇关于从istream读取boost :: variant类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆