2015-01-03 3 views
0

부스트 :: 변형에서 int 값을 얻으려고합니다. 코드 생성 세분화 오류 - 왜? 오류를 생성하는 코드에 주석을 넣습니다. 나는 제대로 작동하지 않습니다부스트 :: 변종에서 세그먼트 화 오류를 생성하십시오.

int numberInt = boost::get<int>(v); 

그래서 컴파일하지만 여전히 내가 int 값을 얻기 위해 관리하고 있지 않다

int *ptrInt = boost::get<int>(&v); 

로 변경한다는 생각? 더블과 정확히 동일합니다. 문자열 유형이 작동 중입니다.

#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 

답변

2

나는 당신이 어떤 부스트 변종인지 오해하고 있다고 생각합니다. 라이브러리 설명서에는 variant 유형이 "멀티 유형 단일 값"으로 설명되어 있습니다. (강조 광산). std::string 유형의 값을 할당 했으므로 다른 유형의 값은 variant에 저장되지 않습니다. (union에 비해)에 대한 variantget 함수의 의견에 설명되어 좋은 일이 :

// Retrieves content of given variant object if content is of type T. 
// Otherwise: pointer ver. returns 0; reference ver. throws bad_get. 

그래서, int numberInt = boost::get<int>(v);올바르게 작동 경우, 예외가 발생합니다. int *ptrInt = boost::get<int>(&v);은 널 포인터를 리턴해야합니다. null 포인터를 역 참조하는 것은 정의되지 않은 동작이며 세분화 오류의 원인 일 수 있습니다.

나는 당신이 찾고있는 행동이 tuple (부스트와 스탠다드 모두에서 발견됨)이라고 생각합니다. 간단한 구조체/클래스는 멤버 객체의 이름을 지정하지 않아도 작동합니다.

2

boost::variant이 어떻게 작동했는지 이해하지 못하셨습니까? 형식 이론에서 boost::variant은 Sum 유형이거나 Algebraic Data Type입니다.

은 종종 "노조 차별"기본적으로 (이 경우)처럼 보인다라고 :

struct Variant { 
    size_t index; 
    union { 
     int a; 
     double b; 
     std::string c; 
    } u; 
}; 

을 지금, 당신은 v = 16을 쓸 때 무슨 일하는 것은 :

v.u.a = 16; v.index = 0; 

을 다음 v = 3.1415을 작성하십시오 :

v.u.b = 3.1415; v.index = 1; 

당신이 v = "hello new year"을 쓸 때 마지막으로 무슨 일입니다 :

v.u.c = "hello new year"; v.index = 2; 

주 그 때마다, 현재 활성화가 업데이트됩니다 ... 그리고 노동 조합의 때문에 단 하나의 멤버가되어 union의 어느 멤버 나타내는 index 어느 시점에서든 활성화되어 있습니다. 이 시점 v->index입니다 2에서, 그것은 nullptr를 반환하기 때문에 따라서

int* get_0(Variant* v) { 
    if (v && v->index == 0) { return &v->u.a; } 
    return nullptr; 
} 

과 : 당신이 boost::get<int>(&v)을 사용하는 경우

코드는 실제로 것 같습니다.

그것이 인의 index2 여부를 확인하고, 따라서 v.u.c에 대한 포인터를 반환하기 때문에 작동 유일한 getboost::get<std::string>(&v)입니다.