I am trying to write a program that searches for a node in a tree, starting from a root-node. As I want the search-algorithm to be as generic as possible, I want to use templates, and I want to use SFINAE to check if a given type implements all the functions I need.
To calculate the successors of a node, the type of the node has to have the function successors()
, which returns a vector of nodes:
#include <vector>
class has_successors_t {
public:
virtual std::vector<has_successors_t> successors() = 0;
};
the class to do the search looks like this:
#include <type_traits>
template <class node_t,
class = std::enable_if_t<std::is_base_of<has_successors_t, node_t>::value>>
class breadthFirstSearch {
public:
static node_t search(node_t root_node) {
// search for the target node
}
};
That way I tried to make the program compile only if a given type has a function to calculate its successors. But when I try to do the following:
#include <vector>
class some_node_t : public has_successors_t {
public:
std::vector<some_node_t> successors() {
// return the successors
}
};
I get an error: error: invalid covariant return type for 'virtual std::vector<some_node_t> some_node_t::successors()'
.
So, I know what the error means, but how can I solve problems like this? I could imagine that I am not the first one to encounter problems where I have a base class and a derived class, and I want an overwritten function in the derived class that returns a vector (or array, or queue, or anything like that) which contains elements of the derived class. But I just can't find a solution for that.
Thanks in advance for any help!
Greetings, Sebastian