问题:应该使用哪种专业化foo<std::unique_ptr<int>>
?
注意到int
不是一个类,所以值std::is_class<T>::value
是假和A
版本不匹配。
如果你想使A
版本是用过时的第一个模板参数是std::unique_ptr
,你可以写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
是有史以来真正;如果您希望foo<std::unique_ptr<int>
相符B
, - 但是,如果你写
template <typename T>
struct foo<std::unique_ptr<T>,
typename std::enable_if<true>::type>
{ static int const value = 1; };
(即,其实是相当)的代码不会编译
- 编辑可以(通过示例)创建类型性状如下
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
}
那么,两个'std :: enable_if'语句应该是互补的吧? –
似乎可以解决它,但我的理解是“更专业”的规则应该使这是不必要的。 – Arelius