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

C++ Template w/ Pointers - Could not convert template argument

本文关键字:转换 参数 指针 c++ 模板      更新时间:2023-10-16

我正在尝试实现一个模板

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

有什么想法或想法为什么我会得到这种不一致?

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

编译器告诉你它不能隐式地将最后一个参数0转换为int *,因为当你传递第一个参数为int *时,object_tint *,并且编译器期望int *作为第三个参数。它告诉您0作为类模板的第三个参数是无效的类型。

以下是标准(ISO/IEC 14882:2011(E))必须说的,在"14.3.21模板非类型参数[temp.arg.][#5],第331页:

虽然0是非类型模板的有效模板实参整型,它不是指针类型的非类型模板形参的有效模板实参。然而,(int*)0nullptr是"指向整型的指针"类型的非类型模板形参的有效模板实参。

特别地,实参依赖查找在这种情况下没有任何作用,错误的原因是指针非类型模板实参只允许的转换是:限定转换、数组到指针的转换或者,如果模板参数类型为std::nullptr_t -空指针转换

你真的需要传递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;
}