C++ 从istream读取boost::variant类型

C++ 从istream读取boost::variant类型,c++,boost,boost-variant,C++,Boost,Boost Variant,我正在浏览boost::variant,想知道如何使以下内容起作用 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), /

我正在浏览
boost::variant
,想知道如何使以下内容起作用

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));   
}
typedef boost::variant myval;
int main()
{
std::vec;
标准::ifstream fin(“temp.txt”);
//如何实现以下目标?
std::copy(std::istream\u迭代器(fin),//这也可以来自std::cin吗?
std::istream_迭代器(),
标准:背向插入器(vec);
}

对于类数据成员,我们可以选择重载
>
运算符,但如何使用
myval
实现这一点

myval
只是一种类型。可以根据类型重载运算符

std::istream &operator >>(std::istream &stream, myval &val)
{
    //Put stuff here.
}

至于放什么,这完全取决于您以及您期望或要求流中有什么。

对于
变体,您可以像对待任何其他类型一样重载
操作符>
。但由您实现逻辑来决定从流中读取并存储在
variant
中的类型。下面是一个完整的示例,说明您可能会如何进行:

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

该操作员是否会参与名称查找?恐怕您必须将它放在
boost
std
命名空间中。@nicolas
std::istream&operator>>(std::istream&stream,myval&val){returnstream>>val;}
无法编译。然而
myvalx;标准:cin>>x编译(重载后),但可执行文件crashes@NicolBolas,谢谢,现在通过与jrok的示例关联,我明白了您的意思,这是一个非常好的方法。但由于某种原因,我得到的都是
字符串
。我用的是MingW4.7。2@P0W你是说输出中的所有字符串?即使您输入整数并使用我发布的确切代码?@P0W Nevermind,
if
语句中存在愚蠢的错误,已修复。
Types read:
int
int
int
string
int
string