Шаблон C ++ с указателями - не удалось преобразовать аргумент шаблона - PullRequest
3 голосов
/ 11 ноября 2011

Я пытаюсь реализовать шаблон

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 ]

3 голосов
/ 12 ноября 2011

Вот что говорит стандарт (ISO / IEC 14882: 2011 (E)) в "14.3.21 Шаблонные нетиповые аргументы [temp.arg.nontype] [# 5], страница 331:

Хотя 0 является допустимым аргументом шаблона для нетипичного параметра-шаблона цельный тип, это не допустимый шаблон-аргумент для нетипового шаблона-параметра типа указателя. Тем не менее, оба (int*)0 и nullptr являются допустимыми аргументами шаблона для нетипового шаблона-параметра типа «указатель на int».

В частности, поиск в зависимости от аргумента в этом случае не имеет ничего общего, причина ошибки в том, что единственными допустимыми преобразованиями для аргумента шаблона нетипового указателя являются: квалификационные преобразования, преобразование массива в указатель или, если аргумент шаблона имеет тип std::nullptr_t - преобразование нулевого указателя.

3 голосов
/ 11 ноября 2011

В шаблонах, когда функция / класс разрешается с помощью ADL (Аргумент-зависимый поиск) Вывод аргумента шаблона функции , неявное преобразование отсутствует. Только точно совпадающие параметры могут разрешить создание экземпляра соответствующей шаблонной функции / класса. Это коренная причина ошибки.

Компилятор сообщает, что не может неявно преобразовать последний параметр 0 в int *, поскольку при передаче первого аргумента как int *, object_t равен int *, и компилятор ожидает int * в качестве третий аргумент. Он говорит вам, что 0 является недопустимым типом в качестве третьего аргумента для шаблона класса.

2 голосов
/ 12 ноября 2011

Вам действительно нужно передать экземпляр 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...