I want to provide two different implementations of an operator>> depending on whether the given type is a subclass of a special type:
class A {};
class B : public A{};
class C {};
template<typename T>
std::istream& operator>>(std::istream& is,
std::vector<typename std::enable_if<std::is_base_of<A, T>::value>::type>& vec)
{
std::cout << "Special case called" << std::endl;
return is;
}
template<typename T>
std::istream& operator>>(std::istream& is,
std::vector<T>& vec)
{
std::cout << "General case called" << std::endl;
return is;
}
void main(int argc, char **argv)
{
std::vector<A> a;
std::vector<B> b;
std::vector<C> c;
std::stringstream ss("A string");
ss >> a;
ss >> b;
ss >> c;
}
Which prints
General case called
General case called
General case called
Changing the second operator definition to
template<typename T>
std::istream& operator>>(std::istream& is,
std::vector<typename std::enable_if<!std::is_base_of<A, T>::value>::type>& vec)
{
std::cout << "General case called" << std::endl;
return is;
}
Does not compile because of
error C2678: binary '>>' : no operator found which takes a left-hand operand of type 'std::stringstream'
So I am probably using std::enable_if wrong. But what is correct? Are there problems with the templated std::vector here?
I don't think the std::enable_if is in the most desired position here, I would put it in the return type to enable SFINAE:
template<typename T>
typename std::enable_if<std::is_base_of<A, T>::value,std::istream>::type&
operator>>(std::istream& is,std::vector<T>& vec)
{
std::cout << "Special case called" << std::endl;
return is;
}
template<typename T>
typename std::enable_if<!std::is_base_of<A, T>::value,std::istream>::type&
operator>>(std::istream& is,std::vector<T>& vec)
{
std::cout << "General case called" << std::endl;
return is;
}
live demo
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