如何使用boost库中的变体和任何内部工作?在我正在进行的项目中,我目前使用标记的联合.我想使用其他东西,因为C++中的联合不允许您使用带有构造函数,析构函数或重载赋值运算符的对象.
我查询了任何和变体的大小,并用它们做了一些实验.在我的平台中,variant采用其最长可能类型的大小加上8个字节:我认为我只是8字节的类型信息,其余的是存储值.另一方面,任何只需要8个字节.由于我在64位平台上,我猜任何只是一个指针.
怎么知道它有什么类型?Variant如何通过模板实现它的功能?在使用它们之前,我想更多地了解这些类.
我在Boost.Any和Boost.Variant之间选择时遇到了麻烦.
我什么时候应该使用每一个?
各有哪些优缺点?
我基本上希望从外部来源存储一些状态.
我正在更新一个项目以使用C ++ 17,发现一些实例,遵循该模式的代码在最新版本的clang上导致了编译错误:
#include <boost/variant.hpp>
struct vis : public boost::static_visitor<void>
{
void operator()(int) const { }
};
int main()
{
boost::variant<int> v = 0;
boost::apply_visitor(vis{}, v);
}
Run Code Online (Sandbox Code Playgroud)
在C ++ 17模式下使用clang v8.0,此操作失败,并显示以下错误:
<source>:11:30: error: temporary of type 'boost::static_visitor<void>' has protected destructor
boost::apply_visitor(vis{}, v);
^
/opt/compiler-explorer/libs/boost_1_64_0/boost/variant/static_visitor.hpp:53:5: note: declared protected here
~static_visitor() = default;
Run Code Online (Sandbox Code Playgroud)
但是,它可以在C ++ 14模式下干净地编译。我发现如果将花括号初始化更改vis{}为括号vis(),则可以在两种模式下正确编译。我尝试过的每个gcc版本都允许在C ++ 17模式下使用这两种变体。
这是从C ++ 14到C ++ 17的正确行为更改,还是这是一个叮当响的错误?如果正确,为什么现在在C ++ 17中无效(或者也许一直如此,但是clang仅在较早的标准版本中允许使用)?
据我所知,所有类型的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; // …Run Code Online (Sandbox Code Playgroud) 我想用lambdas内联访问变体类型.目前我有以下代码:
struct Foo {
boost::variant< boost::blank , int , string , vector< int > > var;
template <typename T, typename IL , typename SL , typename VL>
void ApplyOptionals( T& ref, IL&& intOption , SL&& stringOption , VL&& vectorOption ) {
if (var.which() == 1) {
intOption( ref , boost::get< int >(var) );
} else if (var.which() ==2) {
stringOption( ref , boost::get< string>(var) );
} else if (var.which() == 3) {
vectorOption( ref , boost::get< vector< int > >(var) …Run Code Online (Sandbox Code Playgroud) 我已经宣布boost::variant它接受三种类型:string,bool和int.以下代码显示我的变体接受const char*并将其转换为bool.boost::variant接受和转换不在其列表中的类型是否是正常行为?
#include <iostream>
#include "boost/variant/variant.hpp"
#include "boost/variant/apply_visitor.hpp"
using namespace std;
using namespace boost;
typedef variant<string, bool, int> MyVariant;
class TestVariant
: public boost::static_visitor<>
{
public:
void operator()(string &v) const
{
cout << "type: string -> " << v << endl;
}
template<typename U>
void operator()(U &v)const
{
cout << "type: other -> " << v << endl;
}
};
int main(int argc, char **argv)
{ …Run Code Online (Sandbox Code Playgroud) 给定两个相同的boost::variant实例a和b,表达( a == b )是允许的.
但( a != b )似乎未定义.为什么是这样?
我想知道Boost Variant和unionc/c ++中的数据类型之间有什么区别.我知道union数据类型占用相同的内存位置,并且内存区域中最大的数据类型占用了所使用的内存总量,例如
union space {
char CHAR;
float FLOAT;
int INTEGER;
}S;
Run Code Online (Sandbox Code Playgroud)
应该占用4个字节的内存,int并且float是最大和相同的大小.Boost Variant和union数据类型之间在其他方面是否存在相似之处和不同之处?我也知道Boost Variant可以采用任何数据类型,它允许数据类型"多态"(如果我滥用OOP主题词,请纠正我).因此union数据类型也是一种多态性吗?
在答案中
它被提到boost::variant并且std::variant有所不同.
std::variant这些差异的动机是什么?(动机是boost::variant在前C++ 17代码中使用)
目标:
我想在不相关的类型上实现类型安全的动态多态(即函数调用的运行时调度)- 即在没有公共基类的类型上.在我看来,这是可以实现的,或者至少在理论上是合理的.我会尝试更正式地定义我的问题.
问题定义:
鉴于以下内容:
A1, ..., An,每个类型都有一个被调用的方法f,可能具有不同的签名,但具有相同的返回类型 R ; 和boost::variant<A1*, ..., An*>对象v(或任何其他类型的变体),它可以并且必须在任何时候假设任何这些类型的一个值;我的目标是写指令概念上等同于v.f(arg_1, ..., arg_m);将获得在运行时调度的功能Ai::f,如果实际类型包含的价值v是Ai.如果调用参数与每个函数的形式参数不兼容Ai,编译器应该引发错误.
当然我不需要坚持语法v.f(arg_1, ..., arg_m):例如,类似的东西call(v, f, ...)也是可以接受的.
我试图在C++中实现这一点,但到目前为止我还没有找到一个好的解决方案(我确实有很多坏的解决方案).下面我通过"好的解决方案"澄清我的意思.
约束:
一个好的解决方案是让我模仿v.f(...)成语的任何东西,例如call_on_variant(v, f, ...);,并满足以下约束:
f …