std::enable_if
文档说:
一个常见的错误是声明两个仅默认模板参数不同的函数模板。这是非法的,因为默认模板参数不是函数模板签名的一部分,并且声明具有相同签名的两个不同函数模板是非法的。
同一页面上的示例显示了与您类似的情况,并通过更改其中一个重载上的模板来解决它,同时保持函数本身相同的签名:
// #4, enabled via a template parameter
template<class T,
typename std::enable_if<
!std::is_trivially_destructible<T>{} &&
(std::is_class<T>{} || std::is_union<T>{}),
int>::type = 0>
void destroy(T* t)
{
std::cout << "destroying non-trivially destructible T\n";
t->~T();
}
// #5, enabled via a template parameter
template<class T,
typename = std::enable_if_t<std::is_array<T>::value> >
void destroy(T* t) // note, function signature is unmodified
{
for(std::size_t i = 0; i < std::extent<T>::value; ++i) {
destroy((*t)[i]);
}
}
/*
template<class T,
typename = std::enable_if_t<std::is_void<T>::value> >
void destroy(T* t){} // error: has the same signature with #5
*/
因此,您可以在代码中执行类似的操作:
template<typename P, std::enable_if_t<std::is_arithmetic<P>::value, int> = 0>
void f(std::vector<P>* a)
{
// body for arithmetic P
}
template<typename P, typename = std::enable_if_t<std::is_class<P>::value>>
void f(std::vector<P>* a)
{
// body for class P
}
使用标签调度,像这样或类似的:
void f_helper(std::vector<P>* a, std::true_type) {
/* implementation for arithmetic type P */
}
void f_helper(std::vector<P>* a, std::false_type) {
/* implementation for class type P */
}
void f(std::vector<P>* a) {
return f_helper(a, std::is_arithmetic<P>{});
}