2013-07-18 7 views
1

Раньше я пытался задать свой вопрос, но я думаю, что способ, которым я задаю свой вопрос, не является правильным. поэтому я попытался снова здесь: (до сих пор я не знаю, что вопрос будет уместно)Извлечение объектов из boost :: variant

первым я определил

typedef boost::variant<point, Line, Vertex> vec_variant; 
typedef std::vector<vec_variant> vec; 

я пишу функцию такую, что зависит от случая она возвращает точку, линию, Вершина или даже комбинация из них.

vec my_func::select_T(const mesh::section& s, const char* model) const 
{ 
    vec new_vec; 
    . 
    . 
    . 
    . 
//loop over my lines 
    else if (strcmp(model , "Line") == 0) 
    { 
    for(section::lineIterator ite = s.beginLine(); ite != s.endLine(); ++ite) 
    { 
     Line ed = *ite; 
     Point p0 = ed.point(0); 
     Point p1 = ed.point(1); 
     Point p0_modified (/* some modification */ ); 
     Point p1_modified (/* some modification */ ); 

     if(/* some other conditions */) 
     { 
      new_vec.push_back(ed); 
      new_vec.push_back(p0_modified); //note before pushing back any point 
      new_vec.push_back(p1_modified); //first I pushed back line 
     } 

     else if (/* some other conditions */) 
     { 
      . 
      . 
      . 
      vertex m = .......; 
      new_vec.push_back(ed); 
      new_vec.push_back(m); //note before pushing back any point 
            //first I pushed back line 
     } 
     } 
    } 
    } 
     return new_vec; 
    } 

так что в конце мы можем иметь что-то подобное {изд p0_modified, p0_modified, изд, т, е изд, т, е изд, p0_modified, p0_modified, изд м, ....} {Line , точка, точка, линия, Vertex, линия, Vertex, линия, точка, точка, линия, Vertex, ...}

Теперь я называю эту функцию в другой части кода (другой файл)

first I defined a visitor: 

    template<typename T> 
    struct T_visitor : public boost::static_visitor<> 
    { 
     T_visitor(std::vector<T>& v) : zeroVector(v) {} 
     template<typename U> 
     void operator() (const U&) {} 
     void operator() (const T& value) 
     { 
      zeroVector.push_back(value); 
     } 
    private: 
     std::vector<T>& zeroVector; 
    }; 

Я позвонил выше функции здесь:

void func_2(/*......*/) 
{ 
    . //we can use above visitor to store each type (point, line, Vertex) in vactor<point or line or Vertex) 
    . //we do not know what the new_vec is at the end of the loop. the only thing we know is that after each line there 
    . //would be either two points or one vertex 
    . 
    const char *model = "Edge"; 
    . 
    .//How to find line ed and corresponded points? 
    . 
    create_line(Point& p0_modified, Point& p1_modified, Line& ed); //two modified points and line 
    . 
    .//How to find point m and corresponded line? 
    . 
    create_point(m(0), m(1), m(2), Line& ed); //point m coordinates and line 
    . 
    . 
} 

ответ

4

Так ваша структура данных в настоящее время является последовательность Point, Line и Vertex объектов (я буду считать, что Surface в первом предложении опечатка). Вы также знаете дополнительное ограничение, которое должно соблюдать любое Line либо двумя Point s, либо одним Vertex. Теперь вы хотите использовать эту структуру.

Это возможно, но это также раздражает. Могу ли я рекомендовать вам просто изменить структуру данных?

struct LineWithPoints { 
    Line line; 
    Point p1, p2; 
}; 
struct LineWithVertex { 
    Line line; 
    Vertex v; 
}; 
typedef boost::variant<LineWithPoints, LineWithVertex> vec_variant; 
typedef std::vector<vec_variant> vec; 

И измените свой код, чтобы произвести эту последовательность вместо этого. Тогда работа с ним становится тривиальной.

+2

Или 'typedef boost :: variant , Vertex> AfterLine; struct LineWithAfter {Линия линии; AfterLine после; } '. – Yakk

+0

@Sebastian Redl, спасибо, я попытался это сделать. –