Шаблон C ++ и указатели - PullRequest
       22

Шаблон C ++ и указатели

4 голосов
/ 13 апреля 2010

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

/* 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

И файл с определением функции:

/* 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 ++ не поддерживает default-int

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

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

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

ошибка C4430: отсутствует указатель типа - предполагается int.Примечание: C ++ не поддерживает default-int

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

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

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

Любая помощь приветствуется.

Ответы [ 2 ]

7 голосов
/ 13 апреля 2010

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

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 *.

5 голосов
/ 13 апреля 2010
template <class T> 
   typename ItemCollection <T>::Item* ItemCollection<T>::insert( T p, Item* ptr) 
   { 
      // function body 
   } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...