SFINAE 与继承
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::string\n");
}
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("int\n");
}
};
int main()
{
std::string a;
int b = 0;
A::multiple<B>(a, b);
}
如果两个 foo
方法都在同一个 class 中,或者我从正确的 class 强制 foo
(A::foo
for std::string
和 B::foo
用于 int
),但是我需要不止一个 class,因为基础 class 必须是可扩展的。我不能使用简单的专业化,因为我需要更多 SFINAE 功能,例如检测 std::pair
、std::tuple
等。我也不想将 foo 方法从 class 移动到名称空间.你有什么想法我该如何解决这个问题?
这里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("int\n");
}
};
但是
来自namespace.udecl#15.sentence-1:
When a using-declarator brings declarations from a base class into a derived class, member functions and member function templates in the derived class override and/or hide member functions and member function templates with the same name, parameter-type-list, cv-qualification, and ref-qualifier (if any) in a base class (rather than conflicting)
Return类型不算,所以你必须在参数中使用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::string\n");
}
};
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("int\n");
}
};
注意:
你也有错别字
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)
}
我正在寻找以下问题的解决方案:
#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::string\n");
}
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("int\n");
}
};
int main()
{
std::string a;
int b = 0;
A::multiple<B>(a, b);
}
如果两个 foo
方法都在同一个 class 中,或者我从正确的 class 强制 foo
(A::foo
for std::string
和 B::foo
用于 int
),但是我需要不止一个 class,因为基础 class 必须是可扩展的。我不能使用简单的专业化,因为我需要更多 SFINAE 功能,例如检测 std::pair
、std::tuple
等。我也不想将 foo 方法从 class 移动到名称空间.你有什么想法我该如何解决这个问题?
这里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("int\n");
}
};
但是
来自namespace.udecl#15.sentence-1:
When a using-declarator brings declarations from a base class into a derived class, member functions and member function templates in the derived class override and/or hide member functions and member function templates with the same name, parameter-type-list, cv-qualification, and ref-qualifier (if any) in a base class (rather than conflicting)
Return类型不算,所以你必须在参数中使用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::string\n");
}
};
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("int\n");
}
};
注意:
你也有错别字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)
}