C++ 从boost获取int::variant生成分段错误

C++ 从boost获取int::variant生成分段错误,c++,boost,get,int,boost-variant,C++,Boost,Get,Int,Boost Variant,我试图从boost::variant获取int值。代码生成分段错误-为什么? 我把注释放在代码中,代码行会产生错误。我以为 int numberInt = boost::get<int>(v); int numberprint=boost::get(v); 无法正常工作,因此我将其更改为 int *ptrInt = boost::get<int>(&v); int*ptrInt=boost::get(&v); 哪一个正在编译,但仍然无法获取int值?与do

我试图从boost::variant获取int值。代码生成分段错误-为什么? 我把注释放在代码中,代码行会产生错误。我以为

int numberInt = boost::get<int>(v);
int numberprint=boost::get(v);
无法正常工作,因此我将其更改为

int *ptrInt = boost::get<int>(&v);
int*ptrInt=boost::get(&v);
哪一个正在编译,但仍然无法获取int值?与double完全相同。字符串类型正在工作

#include <iostream>
#include "boost/variant.hpp"
#include <boost/variant/get.hpp>
using namespace std;

int main(int argc, char* argv[])
{
  boost::variant<int, double, std::string> v;
  v = 16;
  v = 3.1415;
  v = "hello new year";

  //int numberInt = boost::get<int>(v);     //1) not working
  //double numberDouble = boost::get<double>(v);//2) not working

  int *ptrInt = boost::get<int>(&v);        //3) compiling
  if(ptrInt) 
    cout << *ptrInt << endl;            //4) not displayed
  //cout << *ptrInt << endl;            //5) segmentation fault

  double *ptrDouble = boost::get<double>(&v);   //6) compiling
  if(ptrDouble) 
    cout << *ptrDouble << endl;         //7) not displayed
  //cout << *ptrDouble << endl;         //8) segmentation fault

  std::string caption = boost::get<string>(v);
  cout << caption << endl;          //9) working

  return 0;
}

// clear && clear && g++ test.cpp -std=c++11 -o test && ./test
#包括
#包括“增压/变型.hpp”
#包括
使用名称空间std;
int main(int argc,char*argv[])
{
boost::变体v;
v=16;
v=3.1415;
v=“新年好”;
//int numberprint=boost::get(v);//1)不工作
//double numberDouble=boost::get(v);//2)不工作
int*ptrInt=boost::get(&v);//3)编译
如果(打印)

cout我认为您误解了boost变量是什么。库的文档将
变量
类型描述为“多类型,单值”(我的重点)。由于您分配了类型为
std::string
的值,因此
variant
中不会存储其他类型的值。
variant
(与
union
相比)的优点在
get
函数的注释中描述:

// Retrieves content of given variant object if content is of type T.
// Otherwise: pointer ver. returns 0; reference ver. throws bad_get.
因此,如果
int*ptrInt=boost::get(v);
工作正常,它应该抛出一个异常。并且
int*ptrInt=boost::get(&v);
应该返回一个空指针。取消引用空指针是未定义的行为,可能是分段错误的原因


我认为您正在寻找的行为是在
tuple
(在boost和std中都可以找到)。如果您不介意为成员对象命名,简单的结构/类也可以工作。

我认为您误解了boost变体是什么。库的文档将
变体
类型描述为“多类型,单值”(我的重点)。由于您分配了类型为
std::string
的值,因此
变量
中不会存储其他类型的值。
变量
(与
联合
相比)的优点在
获取
函数的注释中描述:

// Retrieves content of given variant object if content is of type T.
// Otherwise: pointer ver. returns 0; reference ver. throws bad_get.
因此,如果
int*ptrInt=boost::get(v);
工作正常,它应该抛出一个异常。并且
int*ptrInt=boost::get(&v);
应该返回一个空指针。取消引用空指针是未定义的行为,可能是分段错误的原因


我认为您正在寻找的行为是在
tuple
(在boost和std中都可以找到)。如果您不介意为成员对象命名,简单的结构/类也可以工作。

恐怕您不明白
boost::variant
是如何工作的。在类型理论中,
boost::variant
是一种求和类型,或者

这也通常被称为“歧视性联盟”,基本上看起来(在本例中):

现在,当您编写
v=16
时,发生的是:

v.u.a = 16; v.index = 0;
v.u.b = 3.1415; v.index = 1;
v.u.c = "hello new year"; v.index = 2;
然后写入
v=3.1415
时发生的情况是:

v.u.a = 16; v.index = 0;
v.u.b = 3.1415; v.index = 1;
v.u.c = "hello new year"; v.index = 2;
最后,当您编写
v=“hello new year”
时,会发生以下情况:

v.u.a = 16; v.index = 0;
v.u.b = 3.1415; v.index = 1;
v.u.c = "hello new year"; v.index = 2;
请注意,每次更新表示
联盟
的哪个成员当前处于活动状态的
索引
,因此在任何时间点只有联盟的一个成员处于活动状态

使用
boost::get(&v)
时,代码实际上如下所示:

int* get_0(Variant* v) {
    if (v && v->index == 0) { return &v->u.a; }
    return nullptr;
}
因此,由于此时
v->index
2
,它返回一个
nullptr


唯一有效的
get
boost::get(&v)
因为它检查
索引是否为
2
,因此返回一个指向
v.u.c

的指针。恐怕您不理解
boost::variant
是如何工作的。在类型理论中,
boost::variant
是一种求和类型,或者

这也通常被称为“歧视性联盟”,基本上看起来(在本例中):

现在,当您编写
v=16
时,发生的是:

v.u.a = 16; v.index = 0;
v.u.b = 3.1415; v.index = 1;
v.u.c = "hello new year"; v.index = 2;
然后写入
v=3.1415
时发生的情况是:

v.u.a = 16; v.index = 0;
v.u.b = 3.1415; v.index = 1;
v.u.c = "hello new year"; v.index = 2;
最后,当您编写
v=“hello new year”
时,会发生以下情况:

v.u.a = 16; v.index = 0;
v.u.b = 3.1415; v.index = 1;
v.u.c = "hello new year"; v.index = 2;
请注意,每次更新表示
联盟
的哪个成员当前处于活动状态的
索引
,因此在任何时间点只有联盟的一个成员处于活动状态

使用
boost::get(&v)
时,代码实际上如下所示:

int* get_0(Variant* v) {
    if (v && v->index == 0) { return &v->u.a; }
    return nullptr;
}
因此,由于此时
v->index
2
,它返回一个
nullptr

唯一有效的
get
boost::get(&v)
,因为它检查
索引是否为
2
,因此返回指向
v.u.c
的指针