#include <type_traits>
class Base {
public:
virtual bool f() {
return true;
}
};
template<typename T>
class Derived : public Base {
std::enable_if_t< std::is_copy_constructible<T>::value, bool > f() override {
return true;
}
std::enable_if_t< !std::is_copy_constructible<T>::value, bool > f() override {
return false;
}
};
The above code doesn't compile. For some reason I did not manage to understand, the compiler sees the two functions as the same overload before removing one by SFINAE.
What I do not understand, however, is how I am to resolve this problem. The docs I found state I should use templating on the function. That doesn't work, however, because the function is meant to be virtual.
I tried off-loading the problem by calling a non-virtual function, but I cannot get that to compile either:
template<typename T>
class Derived : public Base {
virtual bool f() override {
return f_impl();
}
private:
template< std::enable_if_t< std::is_copy_constructible<T>::value > = 0 >
bool f_impl() {
return true;
}
template< std::enable_if_t< !std::is_copy_constructible<T>::value > >
bool f_impl() {
return false;
}
};
int main() {
Derived<int> a;
std::cout<<a.f()<<"\n";
}
That fails compilation with:
so.cpp: In instantiation of ‘class Derived<int>’:
so.cpp:29:18: required from here
so.cpp:18:10: error: ‘std::enable_if<true, void>::type’ {aka ‘void’} is not a valid type for a template non-type parameter
I'm obviously doing something wrong here, but I can't figure out what would be the correct way.
bool f() override { return std::is_copy_constructible<T>::value; }
? – Orten