问题:调用foo<std::unique_ptr<int>>应该使用哪个专业化?
注意 int 不是一个类,所以 std::is_class<T>::value 的值为 false 并且 A 的版本不匹配。
如果您希望在第一个模板参数是std::unique_ptr 时使用A 版本,您可以将A 版本写为
template <typename T>
struct foo<std::unique_ptr<T>,
typename std::enable_if<std::is_class<
std::unique_ptr<T>>::value>::type>
{ static int const value = 1; };
或者你可以写foo如下
template <typename T,
typename = typename std::enable_if<std::is_class<T>::value>::type>
struct foo;
template <typename T>
struct foo<std::unique_ptr<T>>
{ static int const value = 1; };
template <typename T>
struct foo<T>
{ static int const value = 2; };
所以A 成为比B 更专业的版本,您的代码可以编译。否则,您的 A 版本实际上是比 B 更专业的版本,但编译器无法识别它。
用
观察
template <typename T>
struct foo<std::unique_ptr<T>,
typename std::enable_if<std::is_class<
std::unique_ptr<T>>::value>::type>
{ static int const value = 1; };
代码编译,std::is_class<std::unique_prt<T>>::value永远为真;但是如果你写
template <typename T>
struct foo<std::unique_ptr<T>,
typename std::enable_if<true>::type>
{ static int const value = 1; };
(实际上是等价的)代码无法编译
-- 编辑--
如果您想要 foo<std::unique_ptr<int> 匹配大小写 B,您可以(通过示例)如下创建类型特征
struct foo<T>
{ static int const value = 2; };
template <typename T>
struct proValue
: std::integral_constant<int, 2>
{ };
template <typename T>
struct proValue<std::unique_ptr<T>>
: std::integral_constant<int, std::is_class<T>::value ? 1 : 2>
{ };
并定义foo如下
template <typename T, int = proValue<T>::value>
struct foo;
template <typename T>
struct foo<std::unique_ptr<T>, 1>
{ static int const value = 1; };
template <typename T>
struct foo<T, 2>
{ static int const value = 2; };
以下是完整的可编译示例
#include <memory>
#include <vector>
#include <iostream>
#include <type_traits>
class Test
{ };
template <typename T,
typename = typename std::enable_if<std::is_class<T>::value>::type>
struct foo;
template <typename T>
struct foo<std::unique_ptr<T>>
{ static int const value = 1; };
template <typename T>
struct foo<T>
{ static int const value = 2; };
template <typename T>
struct proValue
: std::integral_constant<int, 2>
{ };
template <typename T>
struct proValue<std::unique_ptr<T>>
: std::integral_constant<int, std::is_class<T>::value ? 1 : 2>
{ };
template <typename T, int = proValue<T>::value>
struct bar;
template <typename T>
struct bar<std::unique_ptr<T>, 1>
{ static int const value = 1; };
template <typename T>
struct bar<T, 2>
{ static int const value = 2; };
int main ()
{
std::cout << foo<std::vector<int>>::value << '\n'; // print 2
std::cout << foo<std::unique_ptr<int>>::value << '\n'; // print 1
std::cout << foo<std::unique_ptr<Test>>::value << '\n'; // print 1
std::cout << bar<std::vector<int>>::value << '\n'; // print 2
std::cout << bar<std::unique_ptr<int>>::value << '\n'; // print 2
std::cout << bar<std::unique_ptr<Test>>::value << '\n'; // print 1
}