C++模板和指针

Kar*_*ary 4 c++ templates pointers

我有模板和指针的问题(我认为).以下是我的代码的一部分:

/* 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
Run Code Online (Sandbox Code Playgroud)

和具有功能定义的文件:

/* 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
   }
Run Code Online (Sandbox Code Playgroud)

以下是此行代码生成的错误:

Item* ItemCollection <T>::insert( T p, Item* ptr)
Run Code Online (Sandbox Code Playgroud)

错误:

错误C2143:语法错误:缺少';' 在'*'之前

错误C4430:缺少类型说明符 - 假定为int.注意:C++不支持default-int

错误C2065:'类型':未声明的标识符

错误C2065:'类型':未声明的标识符

错误C2146:语法错误:在标识符'p'之前缺少')'

错误C4430:缺少类型说明符 - 假定为int.注意:C++不支持default-int

错误C2470:'ItemCollection :: insert':看起来像一个函数定义,但是没有参数列表; 跳过明显的身体

错误C2072:'ItemCollection :: insert':函数的初始化

错误C2059:语法错误:')'

任何帮助深表感谢.

Dav*_*eas 7

简短的回答是Alexey已经发布的内容:

template <typename T>
typename ItemCollection<T>::Item* ItemCollection<T>::insert( T p, Item * ptr ) {
   // ...
}
Run Code Online (Sandbox Code Playgroud)

(要理解为什么typename需要,搜索SO以获取相关问题,或者删除注释.我将把注意力集中在查找规则中,解释为什么必须以不同方式声明返回和参数类型)

解释是c ++中的查找规则对返回类型和其余参数具有不同的范围.当编译器看到定义时A B::c( D ),A会在定义的封闭命名空间中进行检查B.当编译器发现::cc在类中查找时B.此时,定义B的其余部分在其余参数的类范围内.这意味着如果返回类型是类的内部类型,则必须使用返回类型的限定名称,而在D编译器的情况下,首先在类中查找它B.

这就解释了为什么返回类型必须完全限定,即使最后一个参数不是.当Item * ptr编译器找到参数时,它已经在类的范围内,并且它将在那里找到它.另一方面,Item封闭命名空间中没有定义.

升级标准中的一个变化将解决这个问题,即使它没有考虑到这个目的而设计.如果我没记错,下面的语法应该在没有完整类型限定的情况下编译:

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

原因完全一样.在ItemCollection<T>::insert解析之后,剩余的令牌将在ItemCollection<T>范围内被验证,包括-> Item *返回定义.


Ale*_*tov 5

template <class T> 
   typename ItemCollection <T>::Item* ItemCollection<T>::insert( T p, Item* ptr) 
   { 
      // function body 
   } 
Run Code Online (Sandbox Code Playgroud)

  • 也许你可以编辑你所做的改变的解释? (5认同)
  • 我知道,但对于学习C++的人解释为什么他们的代码出现问题然后只是给他们代码以便他们可以解决问题更有帮助; 否则什么也没有学到,他们再次回到SO同样的问题.特别是对于`typename`关键字的需求,这是C++中常常无法理解的.即使OP了解他做错了什么,解释也会帮助那些通过Google找到这个问题的人. (5认同)