我正在研究 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));
}
对于类数据成员,我们可以选择重载 >>>
运算符,但是如何使用 myval
来重载呢?
最佳答案
您可以为 variant
重载 operator>>
,就像任何其他类型一样。但是由您来实现逻辑来决定从流中读取什么类型并将其存储在 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';
}
}
示例输入:1 2 3 hello 4 world
输出:
Types read:
int
int
int
string
int
string
关于c++ - 从 istream 读取一个 boost::variant 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18009759/