Partial specialisation 的 template 函数(包括成员函数)是不允许的。一种选择是使用SFINAE 重载。例如,
/// auxiliary for is_std_vetor<> below
struct convertible_from_std::vector
{
template<typename T>
convertible_from_std::vector(std::vector<T> const&);
};
template<typename V>
using is_std_vector
= std::is_convertible<V,convertible_from_std_vector>;
class Foo
{
public:
template<typename T, std::enable_if_t< is_std::vector<T>::value,T>
Get()
{
std::cout << "vector" << std::endl;
return T();
}
template<typename T, std::enable_if_t<!is_std::vector<T>::value,T>
Get()
{
std::cout << "generic" << std::endl;
return T();
}
};
请注意,辅助类 is_std_vector 在其他情况下也可能有用,因此值得在某个地方使用。进一步注意,您可以通过请求任何std::vector 或特定的std::vector<specific_type, specific_allocator> 来使这个助手类更加通用。例如,
namespace traits {
struct Anytype {};
namespace details {
/// a class that is convertible form C<T,T>
/// if either T==AnyType, any type is possible
template<template<typename,typename> C, typename T1=Anytype,
typename T2=Anytype>
struct convCtTT
{
convCtTT(C<T1,T2> const&);
};
template<template<typename,typename> C, typename T1=Anytype>
struct convCtTT<C,T1,AnyType>
{
template<typename T2>
convCtTT(C<T1,T2> const&);
};
template<template<typename,typename> C, typename T2=Anytype>
struct convCtTT<C,AnyType,T2>
{
template<typename T1>
convCtTT(C<T1,T2> const&);
};
template<template<typename,typename> C>
struct convCtTT<C,AnyType,AnyType>
{
template<typename T1, typename T2>
convCtTT(C<T1,T2> const&);
};
}
template<typename Vector, typename ValueType=AnyType,
typename Allocator=AnyType>
using is_std_vector
= std::is_convertible<Vector,details::convCtTT<std::vector,ValueType,
Allocator>;
}