0

在过去的三天里,我一直在尝试找出如何实现一种从 boost::variant<...> 中获取价值的通用方法,但这非常困难。

这是我能想出的解决方案,它根本不是通用的:

#include <iostream>
#include "boost\variant\variant.hpp"

using MyVariant = boost::variant<int, std::string>;

class VariantConverter : public boost::static_visitor<>
{
private:
    mutable int _int;
    mutable std::string _string;

    static VariantConverter apply(MyVariant& v) 
    {
        VariantConverter res;

        v.apply_visitor(res);

        return res; // copy will be elided, right?
    }

public:
    void operator()(int& i) const
    {
        _int = i;
    }

    void operator() (std::string& s) const
    {
        _string = s;
    }

    static int to_int(MyVariant v) 
    {
        return apply(v).from_int();
    }

    static std::string to_string(MyVariant v) 
    {
        return apply(v).from_string();
    }

    int from_int() 
    { 
        return _int; 
    };

    std::string from_string() 
    { 
        return _string; 
    };
};

int main()
{
    using namespace std;

    MyVariant v = 23;

    int i = VariantConverter::to_int(v);

    cout << i << endl;

    v = "Michael Jordan";

    std::string s = VariantConverter::to_string(v);

    cout << s.c_str() << endl;

    cin.get();

    return 0;
}

如果有人可以指导我找到更好的解决方案,我将不胜感激。

或者也许有人可以向我解释这背后的理由:

如果我声明:

using MyVariant = boost::variant<int, std::string>;

然后是:

ConverterToInt : basic_visitor<int> {
public:
    int operator() (int i) { return i; };
};

为什么当我尝试将 ConverterToInt 应用于 MyVariant 时:

ConverterToInt cti;

MyVariant i = 10;

i.apply_visitor(cti);

我得到一个编译器错误,试图找到一个带有 std::string 的 operator()?

在我看来,apply_visitor 正在尝试为 MyVariant 可以采用的每种类型调用 operator() 。是这样吗?如果是,为什么?我怎样才能避免这种行为?

干杯!

4

2 回答 2

1

您可以通过告诉ConverterToInt如何处理std::string. 您可能知道这i不可能,std::string但期望编译器知道这一点是不合理的(如果这是真的,您为什么要使用变体?)。

apply_visitor只会调用正确的operator()方法,但它在运行时决定,编译器需要涵盖所有可能性来生成代码。

于 2014-04-24T00:51:57.793 回答
0
MyVariant iv = 10;    
int i = boost::get<int>(iv);

boost::variant 在调用时不会“调用”接口的每个 operator(),但它必须能够。这就是重点。变体可以包含任何模板类型,因此如果要在其上定义操作,则必须在某处指定该操作对每种类型的含义。

于 2014-10-15T21:41:15.843 回答