我正在寻找以下问题的解决方案:
#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::string
为A::foo
,int
为B::foo
(,那么所有方法都可以正常工作,但是我需要多个类,因为基类必须是可扩展的。我不能使用简单的专业化,因为我需要更多的SFINAE功能,如检测std::pair
、std::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)
}