C ++ pattern and pointers

I have a problem with pattern and pointers (I think). The following is part of my code:

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

And the file with the defintion function:

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

Here are the errors that are generated by this line of code:

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

Errors:

error C2143: syntax error: missing ';' before '*'

error C4430: missing type specifier - int. Note: C ++ does not support default-int

error C2065: "Type": undeclared identifier

error C2065: "Type": undeclared identifier

error C2146: syntax error: missing ')' before identifier 'p'

error C4430: missing type specifier - int. Note: C ++ does not support default-int

error C2470: "ItemCollection :: insert": looks like a function definition, but there is no list of parameters; skipping the visible body

error C2072: 'ItemCollection :: insert': function initialization

error C2059: syntax error: ')'

Any help is greatly appreciated.

+4
source share
2 answers
 template <class T> typename ItemCollection <T>::Item* ItemCollection<T>::insert( T p, Item* ptr) { // function body } 
+6
source

The short answer is what Alexey has already posted:

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

(To understand why typename is required, do a SO search for related questions or drop a comment. I will concentrate the answer in the search rules, which will explain why return types and argument types should be declared differently)

The explanation is that C ++ search rules have different applications for the return type and other parameters. When the compiler sees the definition AB::c( D ) , A checked in the enclosing namespace of the definition, just like B When the compiler finds ::c , it searches for c inside class B At this point, the rest of the definition is inside the scope of class B for the remaining parameters. This means that if the return type is an internal type of the class, you must use a qualified name for the return type, whereas in the case of D compiler first looks for it inside the class B

This explains why the return type must be fully qualified, even if the last parameter is missing. When the parameter Item * ptr found by the compiler, it already enters the scope of the class, and it will find it there. On the other hand, there is no Item in the encompassing namespace.

One of the changes in the raising standard will deal with this, even if it has not been developed for this purpose. If I remember correctly, the following syntax should compile without a full type qualification:

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

The reason is exactly the same. After analyzing the ItemCollection<T>::insert remaining tokens will be checked inside the ItemCollection<T> , including the return definition -> Item * .

+6
source

Source: https://habr.com/ru/post/1306790/


All Articles