Why is the second call to print_all function is causing a static semantic error?
#include <list>
using std::list;
class foo {
// ...
};
class bar : public foo {
// ...
};
static void print_all(list<foo*>& L) {
// ...
}
list<foo*> LF;
list<bar*> LB;
// ...
print_all(LF); // works fine
print_all(LB); // static semantic error
The std::list is a template class, meaning, one needs to instantiated with a type, to get the full class definition for the required templated class. When the std::list has been instantiated with foo and bar, we get completely different types. That means the bar is a foo(due to the inheritance), but the std::list<foo*> is different type than std::list<bar*>. Therefore, the print_all(std::list<foo*> &L) can only take the list of pointers to foo 's, as per the given definition.
The simplest solution to the problem is the templated function. Make the print_all function templeted one, by which it can also accept other types(i.e. std::list<foo*>, std::list<bar*>, etc...) too.
template<typename Type> // --> template parameter
void print_all(std::list<Type*> const& L) // --> function parameter
// ^^^^^^ --------> use `const-ref` as the list is
// not being modified inside the function
{
// print the list
}
However, that will now accept other types too, such as std::list<int*>, std::list<float*>, etc..(all other possible types). This might not be the behaviour you want. There we have so-called "Substitution Failure Is Not An Error" (SFINAE) technique, by which one can restrict the instantiation of the templated print_all function, if and only if, the template Type std::is_base_of the foo class. Something like
#include <type_traits> // std::enable_if, std::is_base_of
template<typename T>
auto print_all(std::list<T*> const& L)-> std::enable_if_t<std::is_base_of_v<foo, T>> // in C++14
// or
// auto print_all(std::list<T*> const& L)-> typename std::enable_if<std::is_base_of<foo, T>::value>::type // in C++11
{
// print the list
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With