문제

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

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

도움이 되었습니까?

해결책

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

Example input: 1 2 3 hello 4 world

Output:

Types read:
int
int
int
string
int
string

다른 팁

myval is just a type. You overload operators based on types.

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

As for what to put there, that's entirely up to you and what you expect or require there to be in the stream.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top