myW*_*SON 41 c++ boost boost-variant
据我所知,所有类型的boost.variant都被解析成真实的类型(意思是variant<int, string> a; a="bla-bla"
在编译之后就好像是转换string a; a="bla-bla"
)所以我想知道:如何获得什么类型被放入boost变体?
我试过了什么:
#include <boost/variant.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
int main()
{
typedef boost::function<double (double x)> func0;
typedef boost::function<double (double x, double y)> func1;
typedef boost::variant<int, func0, func1> variant_func;
func1 fn = std::plus<double>();
variant_func v(fn);
std::cout << boost::get<func1>(v)(1.0, 1.0) << std::endl; // this works
//std::cout << boost::get<v::type>(v)(1.0, 1.0) << std::endl; // this does not compile with many errors
// std::cout << (v)(1.0, 1.0) << std::endl; // this fails with Error 1 error C2064: term does not evaluate to a function taking 2 arguments
std::cin.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Fer*_*cio 33
v.which()
将返回当前持有的对象类型的从0开始的索引.
当您检索对象时,您的代码必须使用静态类型(为了满足get<T>
函数模板)来引用(有效)动态类型的对象.
您需要测试类型(使用which()
或type()
)并相应地进行分支或使用静态访问者.无论选择哪种方式,都必须显式声明要检索的静态类型,并且必须与动态类型匹配,否则将抛出异常.
绕过这个问题的一种方法是不使用直接使用变量类型,而是在内部使用包含变量类型的类,然后定义使用该对象所需的任何隐式转换运算符.
我有一个名为Dynamic C++的项目,它使用这种技术.
ken*_*ytm 18
boost.variant
如果已启用RTTI,则具有可以返回活动类型的typeid的.type()
函数.
您还可以定义静态访问者以根据变体内容的类型执行操作,例如
struct SomeVisitor : public boost::static_visitor<double>
{
double operator()(const func0& f0) const { return f0(1.0); }
double operator()(const func1& f1) const { return f1(1.0, 1.0); }
double operator()(int integer) const { return integer; }
};
...
std::cout << boost::apply_visitor(SomeVisitor(), v) << std::endl;
Run Code Online (Sandbox Code Playgroud)
ric*_*rdr 11
您可以使用以下两者导致std :: type_info对象:
与成员函数std :: type_info :: operator ==一起检查boost :: variant当前存储的类型.例如,
boost::variant<int, bool, std::string> container;
container = "Hello world";
if (container.type() == typeid(std::string)) {
std::cout << "Found a string: " << boost::get<std::string>(container);
}
else if (container.type() == typeid(int)) {
std::cout << "Found an int: " << boost::get<int>(container);
}
Run Code Online (Sandbox Code Playgroud)