过去三天我一直试图弄清楚如何实现一种从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>;
然后a:
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()。是这样吗?如果是,为什么?我该如何避免这种行为?
干杯!
答案 0 :(得分:1)
您可以通过告知ConverterToInt
如何处理std::string
来避免错误消息。你可能知道i
不能是std::string
但是期望编译器知道它是不合理的(如果它是真的,你为什么要使用变体?)。
apply_visitor
只会调用正确的operator()
方法,但它会在运行时决定,并且编译器需要具备生成代码的所有可能性。
答案 1 :(得分:0)
MyVariant iv = 10;
int i = boost::get<int>(iv);
boost :: variant在调用时不会“调用”接口的每个operator(),但它必须能够。这就是重点。变量可以包含任何模板类型,因此如果要在其上定义操作,则必须指定该操作对每种类型的含义。