我正在尝试实施模板
template <class object_t, long size, object_t nullObject>
class lf_deque
{
// ...
}
当我尝试使用int实例化此模板时,它编译得很好,但如果我尝试用指针实例化,我会收到错误:
could not convert template argument '0' to 'int*'
的
lf_deque<int, 10, 0> intDeque; // WORKS
lf_deque<int*, 10, 0> ptrDeque; // ERROR
为什么我会出现这种不一致的任何想法或想法?
答案 0 :(得分:3)
在使用 ADL(Argument Dependent Lookup) 函数模板参数演绎解析函数/类时的模板中,没有隐式转换。只有完全匹配的参数才能解析为实例化适当的模板函数/类。这是错误的根本原因。
编译器告诉您它无法将最后一个参数0
隐式转换为int *
,因为当您将第一个参数作为int *
传递时,object_t
为int *
并且编译器也期望int *
作为第三个参数。它告诉您0
是一个无效类型,作为类模板的第三个参数。
答案 1 :(得分:3)
这是标准(ISO / IEC 14882:2011(E))必须说的,“14.3.21模板非类型参数[temp.arg.nontype] [#5],第331页:
虽然0是非类型模板参数的有效模板参数 积分型,它不是 指针类型的非类型模板参数的有效模板参数。但是,
(int*)0
和nullptr
是非类型模板参数的有效模板参数,类型为“指向int的指针”。
特别是,在这种情况下,与参数相关的查找无关,错误的原因是指针非类型模板参数的唯一允许转换是:限定转换,数组到指针转换
或者,如果模板参数的类型为std::nullptr_t
- 空指针转换。
答案 2 :(得分:2)
你真的需要传递nullObject实例作为模板的一部分吗?你可以通过构造函数来完成它吗?
以下使用g ++编译
#include <string>
template <class object_t, long size>
class lf_deque
{
public:
lf_deque(const object_t& nullObject){
//...
};
protected:
lf_deque(){
// ...
};
};
int main(){
lf_deque<int,10> intDeque(0);
lf_deque<std::string,10> myStringDeque("");
int myInt = 4;
lf_deque<int*,10> intPtrDeque(&myInt);
lf_deque<int*,10> intPtrDequeZero(0);
return 0;
}
如果这不可行,也许您可以将值存储为静态成员。
#include <string>
template <class object_t, long size>
class lf_deque
{
public:
lf_deque(){
//..
}
static object_t nullObject;
};
template<class object_t, long size> object_t lf_deque<object_t,size>::nullObject;
int main(){
lf_deque<int,10>::nullObject = 0;
lf_deque<int,10> intDeque;
lf_deque<int*,10>::nullObject = 0;
lf_deque<int*,10> intPtrDeque;
return 0;
}