2011-09-06 2 views
0

named_graph mixin을 사용하여 실험하고 있는데, remove_vertex()가 어떻게 작동해야하는지 조금 혼란 스럽습니다.부스트 그래프 라이브러리 : named_graph and remove_vertex

#include <iostream> 
#include <string> 
#include <boost/lexical_cast.hpp> 
#include <boost/graph/adjacency_list.hpp> 

struct vertex_info { 
    std::string name;   // uses vertex_from_name<vertex_info> 
    vertex_info(const std::string &name_) : name(name_) { } 
}; 

ostream& operator<<(ostream & os, const vertex_info &v) 
{ 
    os << v.name; 
    return os; 
} 

namespace boost { namespace graph { 

template<typename Type> 
struct vertex_name_extractor 
{ 
    typedef Type type; 
    typedef const std::string& result_type;  
    result_type operator()(const Type& v) const 
    { 
    return v.name; 
    } 
}; 

template<> 
struct internal_vertex_name<vertex_info> 
{ 
    typedef vertex_name_extractor<vertex_info> type; 
}; 

template<> 
struct internal_vertex_constructor<vertex_info> 
{ 
    typedef vertex_from_name<vertex_info> type; 
}; 

} } 

typedef adjacency_list< vecS, vecS, undirectedS, vertex_info, edge_info> graph_t; 

namespace bg=boost::graph; 
int main() 
{ 
    using namespace std; 
    graph_t g; 

    int i; 
    typedef graph_traits<graph_t>::vertex_descriptor vert; 

    for(i=0;i < 10;++i) 
    { 
    string t_name("Vertex"); 
    vert V; 
    t_name += lexical_cast<string>(i); 
    V = add_vertex(t_name,g); 
    } 

    typedef graph_t::vertex_name_type name_t; 
    name_t s_temp("Vertex2"); 

    optional<vert> V(
    find_vertex(s_temp,g)); 

    if(V) { 
    cout << "Found vertex:" << *V << '\n'; 
    //remove_vertex(*V,g);   // (1) 
    //remove_vertex(vertex(*V,g),g); // (2) 
    //remove_vertex(g[*V],g);  // (3) 
    //remove_vertex(s_temp,g);  // (4) 
    } else { 
    cout << "Vertex not found\n"; 
    } 


    graph_traits<graph_t>::vertex_iterator v_i, v_end; 

    for(tie(v_i,v_end) = vertices(g); v_i != v_end; ++v_i) 
    { 
    cout << '\'' << g[*v_i] << '\'' << endl;; 
    } 
} 

내가 사용하려고 (3) 또는 (4), 나는 '(& vertex_info, &을 graph_t) remove_vertex'에 일치하는 함수 호출에 대한 오류가

adjacency_list.hpp : 2,211 후보 : remove_vertex (typename graph_t :: vertex_descriptor, graph_t &)

하지만 (1) 또는 (2)를 사용하면 'unsigned int'에서 'const char *'로 잘못된 변환 오류가 발생합니다.

error: initializing argument 1 of ‘std::basic_string<...' 
    boost/graph/named_graph.hpp:349 
    template<BGL_NAMED_GRAPH_PARAMS> 
    inline void BGL_NAMED_GRAPH::removing_vertex(Vertex vertex) 
    { 
     named_vertices.erase(vertex); //line 349 
    } 

답변

0

vertex_name 추출기의 result_type에는 const 및 참조 한정자가 제거되어야합니다. 함수 객체는 const 참조를 반환하도록 지정해야합니다. 이것은 result_type을 제거하지 않고 의존하는 적절한 메타 기능을 허용합니다. 오버로드 된 펑터를 쉽게 지정할 수 있습니다.

template<typename Type> 
struct vertex_name_extractor 
{ 
typedef Type type; 
    typedef std::string result_type;                 
    const result_type& operator()(const Type& v) const          
    {   
    return v.name; 
    }   
} ; 

우리 자신의 생성자를 지정하면 번들 VertexProperty를 쉽게 생성 할 수 있습니다.

template<typename VertexProperty>               
struct vertex_info_constructor 
{ 
    typedef VertexProperty return_type;              
    typedef typename vertex_name_extractor<VertexProperty>::result_type argument_type;  
    return_type operator()(argument_type n)             
    {                      
    VertexProperty v(n); 
    return v; 
    }                      
}; 

template<>                     
struct internal_vertex_constructor<vertex_info>           
{ 
    typedef vertex_info_constructor<vertex_info> type;          
}; 

adjacency_list에는 기본 클래스 maybe_named_graph <>로, MI 믹스 인을 사용합니다.

는 는 는

지금 adjacency_list에의 remove_vertex (VertexDescriptor, 그래프) 내 전문을 호출

template<typename Graph, typename Vertex> 
struct maybe_named_graph<Graph, Vertex, vertex_info, vertex_name_extractor<vertex_info> > 
    : public named_graph<Graph, Vertex, vertex_info> 
{ 
    typedef named_graph<Graph, Vertex, vertex_info> Base; 
    //maybe_named_graph() { } 

    typedef typename detail::extract_bundled_vertex<vertex_info>::type 
    bundled_vertex_property_type; 

    void added_vertex(Vertex v) { Base::added_vertex(v); } 

    void removing_vertex(Vertex v) { 
      const std::string &name = extract_name((Base::derived()[v])); 
      Base::named_vertices.erase(name); 
    } 

    void clearing_graph() { Base::clearing_graph(); } 

    optional<Vertex> 
    vertex_by_property(const bundled_vertex_property_type& t) 
    { 
    return Base::vertex_by_property(t); 
    } 
}; 
다음과 같이 는 internal_vertex_name :: 형이 무효 인 경우 named_graphs를 해제의 예에 따라, 나는 maybe_name_graph :: 형>의 부분 특수화를 추가 vertex_name을 vertex descriptor에 의해 named_graph에서 제거하는 제거 _ 노드.

참고 : vecS가 사용되므로 여전히 반복기 무효화에주의해야합니다.

관련 문제