Ошибка компилятора при попытке удалить тип шаблона, который является указателем

Я новичок в C ++, и у меня есть амбиции понять, как работают шаблоны. Итак, я реализовал общий список MyList который может содержать как встроенные примитивные типы, так и указатели. в remove Функция Я хочу различать типы указателей и встроенные модули, чтобы можно было удалить объект за указателем, но оставить встроенные элементы без изменений.

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

// distinguish between pointer and non-pointer type of template variable
template<typename T> bool is_pointer(T t) {
return false;
}

template<typename T> bool is_pointer(T* t) {
return true;
}

В функции списка remove Идея заключалась в том, чтобы проверить указатели и удалить их на всякий случай. Однако оператор delete не компилируется:

template<typename T> void MyList<T>::remove() {
...
if (is_pointer(temp->getContent())) {
// delete object pointer points to
T t = temp->getContent();
cout << t;    // prints out address
// delete t;  // produces compiler error (see below)
}

в main.cpp Я тестирую список класса с различными типами, я вызываю среди других:

MyList<int> mylist;                // with type int
mylist.remove();
mylist.add(3);
// add and remove elements

MyList<string> mylist2;           // with type string
...

MyList<string*> mylist3;          // with type string*
mylist.add(new string("three"));
mylist.remove();

Когда я закомментирую заявление delete t; Я могу убедиться, что поток управления корректен: оператор if вводится только для string* пример. Однако, если я раскомментирую delete В заявлении компилятор жалуется так:

../mylist.h: In member function ‘void MyList<T>::remove() [with T = int]’:
../main.cpp:36:18:   instantiated from here
../mylist.h:124:6: error: type ‘int’ argument given to ‘delete’, expected pointer
../mylist.h: In member function ‘void MyList<T>::remove() [with T = std::basic_string<char>]’:
../main.cpp:71:18:   instantiated from here
../mylist.h:124:6: error: type ‘struct std::basic_string<char>’ argument given to ‘delete’, expected pointer
make: *** [main.o] Error 1

Что я не вижу? Я использую delete утверждение только по указателям, но все же я получаю эти ошибки компилятора. Если я распечатаю t в операторе if это адрес указателя!

1

Решение

Шаблон — это проект, который компилятор использует для фактического создания типов на основе использования проекта. Когда вы используете свой шаблон с int а также string* компилятор на самом деле создаст два варианта MyList, заменяя T фактическим типом. Реализация, которая использует int за T является поддельным, потому что удаление int не имеет смысла. Фактический код, который генерирует компилятор:

int t = temp->getContent();
cout << t;
delete t;

Это неверно, как вы могли понять.

1

Другие решения

Если вы создаете экземпляр шаблона с T = int, ты получаешь:

void MyList::remove() {
if (false) {
T t = temp->getContent();
cout << t;
delete t;
}
}

Даже если кодовый блок никогда не выполняется, он должен быть синтаксически правильным.

0

Я предлагаю использовать C ++ 11 type_traits и auto_ptr, как это

#include <type_traits>
template<typename T> void MyList<T>::remove() {
...
if (is_pointer(T)) {
// delete object pointer points to
T t = temp->getContent();
cout << t;    // prints out address
auto_ptr tempobj(T);
}

Также посмотрите на это Определите, является ли Type указателем в шаблонной функции это может быть полезно, если ваш компилятор не совместим с C ++ 11.

Спасибо
Нирадж Рати

0
По вопросам рекламы [email protected]