Почему тип небезопасен в классе шаблонов?

#c #templates #pointers

#c #шаблоны #указатели

Вопрос:

Я столкнулся со странной ошибкой, связанной с классом шаблонов в C . Большую часть времени коды выполняются нормально, но в одном случае произошел сбой. Ниже приведены упрощенные коды:

 template <class T>
class Class1
{
    ...
    T *func();
    ...
};

// ---------------------------------------------------------------

template <class T>
T *Class1<T>::func(...)
{
    ...
    string name = typeid(T).name();
    T *ptr = a_queue.front(); // a_queue is of type "queue<T *>"
    ptr->some_func(); // failed
    ...
}

// ---------------------------------------------------------------

Class1<Class2> class1;
class1.func();
  

Предположим, что Class1 специализируется на T is Class2 и Class3 соответственно. В этом случае Class1<Class2>::func , ptr объявляется как Class3 указатель! Значит, тип небезопасен в классе шаблонов?

Есть идеи? Спасибо!

Редактировать:

Я добавил, string name = typeid(T).name() тогда T будет правильный тип ( Class2 ), но при вызове функции-члена some_func of Class2 возникает ошибка:

 cannot access memory address at 0x10
  

[Решено] Окончательное редактирование 2011/11/09:

Я обнаружил проблему, она не связана с классом шаблонов, но вызвана удалением неправильного указателя, который не обновлен в той же функции с delete и был помещен в очередь!

Комментарии:

1. Вы имеете в виду, Class1 является специализированным? Вы не можете специализироваться T — это просто тип. В Class1<Class2> , T есть Class2 … когда вы получаете «странную ошибку», вы должны опубликовать эту ошибку, потому что компилятор C может напечатать любое количество странных ошибок.

2. Да, Class1 является специализированным. Я ожидаю, что T в Class1<Class2> должно быть Class2 , но это Class3 в моем случае. Нет прямого вывода ошибок, и мои коды довольно огромны, поэтому я не имею ни малейшего представления, как размещать ошибки.

3. Вы выделяете память для ptr by new ? Вы преобразуете выходные данные func() в другой тип? Вопрос очень неоднозначный.

4. Извините за неоднозначный вопрос! Потому что это меня глубоко удивляет. Я не выделяю память для ptr , просто присваиваю ему адрес Class2 объекта в очереди как T *ptr = a_queue.front() .

5. @LiDong, вам нужно придумать полный, минимальный фрагмент кода, который воспроизводил бы проблему, с которой вы столкнулись. Затем вы должны объяснить, какой результат вы получаете и какой результат вы ожидаете.

Ответ №1:

не удается получить доступ к адресу памяти в 0x10

Это эквивалентно ссылке на НУЛЕВОЙ указатель. Компилятор начал с некоторого T *ptr = 0 и попытался найти элемент (или vtable) T со смещением 0x10, чтобы просмотреть память 0 0x10 . Так что я не думаю, что ваша проблема связана с типами шаблонов, а с a_queue.front() содержащими NULL.

Комментарии:

1. Ваш ответ кажется правильным направлением для решения этой странной проблемы.

Ответ №2:

В вашем вопросе есть функция шаблона. Вы создали шаблон для обоих класса и функции?

 template <typename T>
class Class1
{
    template <typename U>
    U *::func(... some argument of U...)
};
  

Это позволило бы вам вызвать Class1<Class2>::func(...some arg Class3...) и попасть func<Class3> внутрь Class1<Class2> .

Комментарии:

1. Да, я создал оба шаблона Class1 и его метод func с T помощью.