2010-04-13 2 views
4

У меня проблема с шаблоном и указателями (я думаю). Ниже часть моего кода:C++ шаблон и указатели

/* ItemCollection.h */ 

#ifndef ITEMCOLLECTION_H 
#define ITEMCOLLECTION_H 

#include <cstddef> 

    using namespace std; 

    template <class T> class ItemCollection 
    { 
    public: 
    // constructor 
     //destructor 

    void insertItem(const T); 

    private: 
     struct Item 
     { 
      T price; 
      Item* left;    
      Item* right;   
     }; 
     Item* root;  
     Item* insert(T, Item*); 

    }; 
#endif 

И файл с функцией Defintion:

/* ItemCollectionTemp.h-member functions defintion */ 

#include <iostream> 
#include <cstddef> 

#include "ItemCollection.h" 

template <class T> 
    Item* ItemCollection <T>::insert(T p, Item* ptr) 
    { 
     // function body 
    } 

Вот ошибки, которые генерируются с помощью этой строки кода:

Item* ItemCollection <T>::insert(T p, Item* ptr) 

Ошибки :

ошибка C2143: синтаксическая ошибка: отсутствует ';' перед '*'

ошибка C4430: отсутствует спецификатор типа - int. Примечание: C++ не поддерживает по умолчанию-INT

ошибка C2065: 'Тип': необъявленный идентификатор

ошибка C2065: 'Тип': необъявленный идентификатор

ошибка C2146: синтаксическая ошибка: отсутствует ')' перед идентификатор 'p'

ошибка C4430: отсутствует спецификатор типа - int. Примечание: C++ не поддерживает default-int

ошибка C2470: «ItemCollection :: insert»: выглядит как определение функции, но список параметров отсутствует; пропуская кажущейся тело

ошибка C2072: 'ItemCollection :: вставка': инициализация функции

ошибка C2059: синтаксическая ошибка: ')'

Любая помощь очень ценится.

+0

@ Kary: Поскольку вы попросили объяснить ответ Алексея, помните, что вы не должны принимать ответ, если только вы на самом деле его не доволен. Если вы хотите более подробно, скажите это и не принимайте его. Или принять другой ответ, который обеспечивает необходимую деталь. – jalf

ответ

6
template <class T> 
    typename ItemCollection <T>::Item* ItemCollection<T>::insert(T p, Item* ptr) 
    { 
     // function body 
    } 
+5

Возможно, вы могли бы изменить объяснение изменений, которые вы сделали? –

+1

Какое объяснение? Я заменяю только неверный 'Item * ItemCollection :: insert (T p, Item * ptr)' by right 'typename ItemCollection :: Item * ItemCollection :: insert (T p, Item * ptr)'. –

+5

Я знаю, но кому-то, кто учит C++, более полезно объяснить, почему у их кода возникла проблема, просто чтобы дать им код, который они могут зайти, чтобы исправить эту проблему; иначе ничего не узнают, и они снова вернутся к SO для той же проблемы. Особенно в связи с необходимостью ключевого слова 'typename', которое часто не понимается на C++. И даже если OP понимает, что он сделал неправильно, объяснение поможет людям, которые находят этот вопрос через Google. –

6

Короткий ответ, что Алексей уже отвечал:

template <typename T> 
typename ItemCollection<T>::Item* ItemCollection<T>::insert(T p, Item * ptr) { 
    // ... 
} 

(Для того, чтобы понять, почему typename требуется, поиск SO для связанных с этим вопросов, или же падение комментарий я остановлюсь ответ в. правила поиска, которые объясняют, почему возвращаемые и типы аргументов должны быть объявлены по-разному)

Объяснение состоит в том, что правила поиска в C++ имеют разные области применения для возвращаемого типа и остальных параметров. Когда компилятор видит определение A B::c(D), A проверяется в охватывающем пространстве имен определения, равно B. Когда компилятор находит ::c, он смотрит вверх c внутри класса B. В этот момент остальная часть определения находится внутри области класса B для остальных параметров. Это означает, что если тип возвращаемого значения является внутренним типом класса, вы должны использовать квалифицированное имя для типа возврата, тогда как в случае D компилятор сначала ищет его внутри класса B.

Это объясняет, почему тип возврата должен быть полностью квалифицирован, даже если последний параметр отсутствует. Когда параметр Item * ptr найден компилятором, он уже входит в сферу действия класса, и он найдет его там. С другой стороны, нет Item, определенных в охватывающем пространстве имен.

Одно из изменений в повышающем стандарте будет иметь дело с этим, даже если оно не было разработано с этой целью. Если я правильно помню, следующий синтаксис должен составить без полной квалификации типа:

template <T> 
auto ItemCollection<T>::insert(T p, Item * ptr) -> Item * 
{ 
    return 0; 
} 

Причина в точности то же самое. После обработки ItemCollection<T>::insert остальные жетоны будут проверяться внутри области ItemCollection<T>, включая определение возврата -> Item *.

Смежные вопросы