【问题标题】:C++ template and pointersC++ 模板和指针
【发布时间】:2011-02-07 10:21:12
【问题描述】:

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

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

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

错误 C2072:“ItemCollection::insert”:函数初始化

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

非常感谢任何帮助。

【问题讨论】:

  • @Kary:既然您要求对 Alexey 的回答做出解释,请记住,除非您真的对此感到满意,否则您不应接受答案。如果你想要更多细节,就说出来,不要接受。或者接受另一个答案,它提供了您想要的详细信息。

标签: c++ pointers templates


【解决方案1】:
template <class T> 
   typename ItemCollection <T>::Item* ItemCollection<T>::insert( T p, Item* ptr) 
   { 
      // function body 
   } 

【讨论】:

  • 也许您可以编辑您所做更改的说明?
  • 什么解释?我只用正确的typename ItemCollection &lt;T&gt;::Item* ItemCollection&lt;T&gt;::insert( T p, Item* ptr) 替换错误的Item* ItemCollection &lt;T&gt;::insert( T p, Item* ptr)
  • 我知道,但是对于学习 C++ 的人来说,解释他们的代码出现问题的原因比给他们提供可以解决问题的代码更有帮助;否则什么都学不到,他们又回到 SO 来解决同样的问题。尤其是对于 typename 关键字的需求,这在 C++ 中通常是不理解的。即使 OP 明白他做错了什么,解释也会帮助通过谷歌找到这个问题的人。
  • 我相信类“范围”在类型命名之后开始,所以返回类型需要完整拼写,但参数不必?
  • -1 没有告诉 OP 为什么需要进行更改。如果提问者没有从中学到任何东西,那么答案就不是很好。
【解决方案2】:

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

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

(要了解为什么需要typename,请搜索相关问题,或者发表评论。我将把答案集中在解释为什么必须以不同方式声明返回和参数类型的查找规则中)

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

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

即将发布的标准中的一项更改将解决这个问题,即使它的设计没有考虑到这个目的。如果我没记错的话,以下语法应该在没有完整类型限定的情况下编译:

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

原因完全一样。在解析 ItemCollection&lt;T&gt;::insert 之后,将在 ItemCollection&lt;T&gt; 范围内验证剩余令牌,包括 -&gt; Item * 返回定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多