std :: is_base_of用于模板化矢量函数参数

Phi*_*Lab 3 c++ templates std c++11

我想提供两种不同的实现,operator>>具体取决于给定类型是否是特殊类型的子类:

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;
}
Run Code Online (Sandbox Code Playgroud)

哪个打印

General case called
General case called
General case called
Run Code Online (Sandbox Code Playgroud)

将第二个运算符定义更改为

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;
}
Run Code Online (Sandbox Code Playgroud)

不编译因为

error C2678: binary '>>' : no operator found which takes a left-hand operand of type 'std::stringstream'
Run Code Online (Sandbox Code Playgroud)

所以我可能std::enable_if错了.但是什么是正确的?std::vector这里的模板有问题吗?

Big*_*ith 8

我不认为std :: enable_if在这里是最想要的位置,我会把它放在返回类型中以启用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;
}
Run Code Online (Sandbox Code Playgroud)

现场演示

  • @PhilLab更喜欢过载而不是函数特化 (3认同)