我正在尝试创建部分专业化的模板,并且如果通过了 std::unique_ptr
template <typename T, typename = void>
struct Foo;
// A
template <typename T>
struct Foo<std::unique_ptr<T>, typename std::enable_if<std::is_class<T>::value>::type> {...};
// B
template <typename T>
struct Foo<T, typename std::enable_if<std::is_class<T>::value>::type> {...};
void fn() {
Foo<std::unique_ptr<T>> foo;
}
我的理解是A比B更专业,应该使用A。但是至少在MSVC 2015中,我得到了错误:
error C2752: 'Foo<FieldT,void>': more than one partial specialization matches the template argument list
我在这里想念什么吗?
问题:应该使用哪个专业名称进行呼叫foo<std::unique_ptr<int>>
?
请注意,这int
不是一个类,因此值std::is_class<T>::value
是false,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
是永远真实的; 但是如果你写
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
,可以(例如)创建一个traits类型,如下所示
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
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句