lundi 27 mars 2017

drops 'const' qualifier template issue

I'm working on an implementation of a graph, along with its most important operations. To obtain ingoing and outgoing edges, i've made use of templates. The edges of my graph are stored in a set, hence why I defined a comparator function. My edges are stored as follows:

 typedef forward_list<const Vertex*> edge_list;
 typedef pair<edge_list, edge_list> neigh_set_entry;
 set<pair<const unsigned, neigh_set_entry>, comp_first> neigh_set;

Where the unsigned value is the type of the edge. The definition of the comparator and match structs are as follows (as I am working on pairs, and I'd like to retrieve a vertex an edge solely based on its type)

struct comp_first {
    template<class A>
    bool operator ()(const pair<const unsigned, A> &a, const pair<const unsigned, A> &b)
    {
        return a.first < b.first;
    }
};

struct match_first {
    match_first(unsigned value) : value(value) {};

    template<class A>
    bool operator()(pair<const unsigned, A> &a) {
        return a.first == value;
    }

    unsigned value;
};

I've used the following code in order to create the as I like to call it direction abstraction for the ingoing and outgoing edges.

struct in {
    static const edge_list& get_list(const pair<edge_list, edge_list> &a) {
        return a.first;
    }
};

struct out {
    static const edge_list& get_list(const pair<edge_list, edge_list> &a) {
        return a.second;
    }
};

These structs are used as template parameter in the following function:

template<class Direction>
const edge_list& get_edges(unsigned relation_id) {
    auto i = find_if(neigh_set.begin(), neigh_set.end(), match_first(relation_id));

    if(i != neigh_set.end()){
        return Direction::get_list(i->second);
    }

    throw RelationException();
}

This is all working out perfectly fine. However, I want to use a similar technique in order to insert edges, as follows:

template<class Direction>
    void add_edge(unsigned relation_id, Vertex &vertex) {
        try {
            auto list = get_edges<Direction>(relation_id);
            list.push_front(&vertex);
        }catch(RelationException& e){
            neigh_set_entry entry;
            Direction::get_list(entry).push_front(vertex);
            neigh_set.emplace(relation_id, entry);
        }
    }

This however, is giving me some trouble. I've removed the const for the in and out structs, aswell for the get_edges function. Yet I keep running in the following error.

error: binding value of type 'const pair<[2 * ...]>' to reference to type 'pair<[2 * ...]>' drops 'const' qualifier

Indicating the following line:

return Direction::get_list(i->second);

Been going around to code for some time, but the only functions marked const are the comparator and the matching structs. What am I missing? Thank you very much in advance.

Aucun commentaire:

Enregistrer un commentaire