I have a class defined as:
template <typename V, typename E>
class AdjacencyList;
Where V and E are the types of the vertex and edge values respectively.
I am currently attempting to define the following member function inside AdjacencyList
:
std::map< std::shared_ptr< Vertex<V, E> >, E > dijkstra(
const std::shared_ptr< Vertex<V, E> > &start_vertex) const;
For those familiar with Dijkstra's algorithm, it is only possible to implement correctly if E
is an addable and non-negative type. Therefore, how do I correctly use the enable_if
construct to only enable this function if E
is an unsigned integral type?
I am currently seeing two complications here that I am uncomfortable with approaching:
E
.E
itself is not used as a type, but is used in other type templates.Because I am relatively new to the enable_if
construct, I would feel more comfortable with some guidance on the issue since this is a relatively non-trivial case.
This is not actually what you want to do.
The point of std::enable_if
is to cause substitution failure for a template. The reason why you want substitution failure is because it's not a failure, and you can select a different overload instead. However, there's no point here because you're not trying to choose a different overload, you're just trying to make it a failure.
So, you'd instead do something like this:
std::map< std::shared_ptr< Vertex<V, E> >, E > dijkstra(
const std::shared_ptr< Vertex<V, E> > &start_vertex) const {
static_assert(
std::is_unsigned<E>::value,
"E must be unsigned.");
}
If you try to call this function with the wrong type of arguments, you get a nice compile-time error telling you that E must be addable and non-negative. If you used enable_if
instead, you'd get an error that none of the overloads were valid, which is a less informative error.
This is probably a bad design, though. Ordinarily you would just throw an exception if you encountered a negative value. Choosing to enforce that the inputs are positive is also incomplete, since the algorithm will also fail if you encounter overflow.
(If you really want to do enable_if
even though it's a bad idea, you can..)
std::enable_if<std::is_unsigned<E>,
std::map<std::shared_ptr<Vertex<V, E>>, E>::type dijkstra...
C++ is the wrong language for this type of programming, and hammering C++ until it works this way will result in some very bizzare C++ code. It sounds like you actually want to write code in Agda.