SFINAE and inheritance



我正在寻找以下问题的解决方案:

#include <string>
class A
{
public:
    template <typename T>
    static typename std::enable_if<std::is_same<T, std::string>::value, void>::type foo(T val)
    {
        printf("std::stringn");
    }
    template<typename T, typename... Arg>
    static void multiple(Arg&&... arg)
    {
        T::foo(arg...);
    }
};
class B : public A
{
public:
    template <typename T>
    static typename std::enable_if<std::is_same<T, int>::value, void>::type foo(T val)
    {
        printf("intn");
    }
};
int main()
{
    std::string a;
    int b = 0;
    A::multiple<B>(a, b);
}

如果两个foo方法都在同一个类中,或者我强制foo来自正确的类(std::stringA::foointB::foo(,那么所有方法都可以正常工作,但是我需要多个类,因为基类必须是可扩展的。我不能使用简单的专业化,因为我需要更多的SFINAE功能,如检测std::pairstd::tuple等。我也不想将foo方法从类移动到命名空间。你知道我该怎么解决这个问题吗?

这里B::foo隐藏A::foo,您需要一个using:

class B : public A
{
public:
    using A::foo;
    template <typename T>
    static typename std::enable_if<std::is_same<T, int>::value, void>::type foo(T val)
    {
        printf("intn");
    }
};

但是

来自namespace.udcl#15.sentence-1:

当using声明符将声明从基类带入派生类时,派生类中的成员函数和成员函数模板会覆盖和/或隐藏基类中具有相同名称、参数类型列表、cv限定符和ref限定符(如果有(的成员函数及成员函数模板(而不是冲突的(

返回类型不计算,因此必须在参数中使用std::enable_if

class A
{
public:
    template <typename T>
    static void foo(T val, std::enable_if_t<std::is_same<T, std::string>::value, int> = 0)
    {
        printf("std::stringn");
    }
};
class B : public A
{
public:
    using A::foo;
    template <typename T>
    static void foo(T val, std::enable_if_t<std::is_same<T, int>::value, int> = 0)
    {
        printf("intn");
    }
};

演示

注意:也有拼写错误

template<typename T, typename... Arg>
static void multiple(Arg&&... arg)
{
    T::foo(arg...); // B::foo(string, int)
}

应该是

template<typename T, typename... Arg>
static void multiple(Arg&&... arg)
{
    (T::foo(arg), ...); // B::foo(string), B::foo(int)
}

最新更新