template<typename vertex_data>
class graph {
typedef std::list<vertex_data> vertex_list;
typedef typename vertex_list::iterator vertex_iterator;
typedef typename vertex_list::const_iterator vertex_const_iterator;
struct edge {
edge(const vertex_iterator &s,const vertex_iterator &d)
:src(s),dst(d) {}
vertex_iterator src;
vertex_iterator dst;
};
typedef std::list<edge> edge_list;
typedef typename edge_list::iterator edge_iterator;
typedef typename edge_list::const_iterator edge_const_iterator;
public:
graph() {}
vertex_iterator add_vertex(const vertex_data v) {
vertices.emplace_back(v);
return vertices.end()-1;
}
edge_iterator add_edge(const vertex_iterator &src,const vertex_iterator &dst) {
edges.emplace_back(src,dst);
return edges.end()-1;
}
private:
vertex_list vertices;
edge_list edges;
};
Being able to get a const_iterator from a iterator would sometimes be indeed useful. Just not the other way around or people start breaking stuff as they tend to do now with const_cast.
An off-topic note about your code: if this is pasted from real-world use you probably want to change the single-argument signature of add_vertex to accept a non-const vetex_data by value and then std::move() it into emplace_back. The current code as it is will always call vertex_data's copy constructor because you cannot move from a const object and you end up with two copy operations instead of one (or even zero if the argument to add_vertex is a temporary).
--
--- You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
>If edge contained const_iterators, it would later be impossible to return non-const references to vertices given edges, while, as is currently implemented, the add_edge function must take non-const iterators, while there is really no reason for it.That seems like the correct thing would be to have non-const iterators there. You intend to modify the object to which the iterator refers; and as such it shouldn't be a const iterator.I'm not saying that this is a bad idea; I'm just saying that example isn't motivating.
> C++11 went one step in the right direction by having functions such as erase and insert take const_iterators. Having a way to obtain iterators from const_iterators would allow a class like the above to do the same.But this breaks const correctness. The reason you have the workaround for the random-access containers is that you have a mutable reference to the container itself which avoids breaking const-correctness.
You would need something like:iterator const_iterator_cast(Container& c, Container::const_iterator i)
This of course makes the assumption that there is some cheap way to recover an iterator given a const iterator; though I suspect 99.99% of the time that is true.> if the compiler is trying to keep track of who might modify what.The compiler cannot use const as a means of determining if someone is modifying something, because const_cast exists in the language. The compiler must be able to prove that the operations done on something are in fact constant operations in order to optimize based on this assumption.> Being able to get a const_iterator from a iterator would sometimes be indeed useful. Just not the other way around or people start breaking stuff as they tend to do now with const_cast.You can already do this -- const iterator has a constructor taking iterator. (e.g. a wchar_t* can turn into a wchar_t const* without a cast; and const_iterator must mimic this behavior)Billy O'Neal
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
That is undefined behavior. The function's preconditions is obvious and ifyou deviate from that then that's outside the function's goal. So,
if you use it for messing with the type system, then it is your fault and
not the function's objective.
The difference is that it requires a *mutable* reference to the container. You aren't converting a const_iterator into an iterator -- you are asking the mutable container for a mutable iterator at the same position as a given const_iterator; which is safe.