带指针的C ++模板 - 无法转换模板参数

时间:2011-11-11 19:21:36

标签: c++ templates

我正在尝试实施模板

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

为什么我会出现这种不一致的任何想法或想法?

3 个答案:

答案 0 :(得分:3)

在使用 ADL(Argument Dependent Lookup) 函数模板参数演绎解析函数/类时的模板中,没有隐式转换。只有完全匹配的参数才能解析为实例化适当的模板函数/类。这是错误的根本原因。

编译器告诉您它无法将最后一个参数0隐式转换为int *,因为当您将第一个参数作为int *传递时,object_tint *并且编译器也期望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;
}