ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I primarily come from a C programming background. Fortunately, but unfortunately I inherited some C++ code. The original author has defined a template class. I'm pretty familiar with this construct. However, the following code template seemed to compile just fine using gcc 2.96. When trying to compile the following code snippet with gcc 3.2-7 it will not compile. First and foremost, I'm wondering what changed within the compile tools which may have caused the code to no longer compile.
Secondly, the code definition of the template class seems a bit strange to me. I was thinking it shoud be
template <class T>
{
body
}
Another question that I have regarding this code snippet is the convention:
DRTINameMap(): hash map......
What does the ":' mean in C++? I'm only used to this being utilized for stuff like a?b:c or public: , private:
I don't expect anybody to understand this code, but I'm just trying to get up to speed on the syntax etc.
Any help would be earnestly appreciated.
Many Thanks,
rong
-------- Original code snippet ----------
template<class DRTITypePtr>
class DRTINameMap :
public hash_map<const char*, DRTITypePtr, str_hash, str_equal> {
public:
DRTINameMap() :
hash_map<const char*, DRTITypePtr, str_hash, str_equal>() {}
I get the following...It's a parse error from the GCC compiler. This compiler is not a specific as some others I have used. I indented the code just as you did. I'm not sure what tokens it's referring to here...
n file included from DRTI.hh:12,
from RegionInfo.cc:1:
DRTI_Factories.hh:54: parse error before `<' token
DRTI_Factories.hh:59: parse error before `&' token
DRTI_Factories.hh:59: ISO C++ forbids declaration of `DRTINameMap' with no type
DRTI_Factories.hh: In function `int DRTINameMap(...)':
DRTI_Factories.hh:59: `int DRTINameMap(...)' redeclared as different kind of
symbol
DRTI_Factories.hh:54: previous declaration of `template<class DRTITypePtr>
class DRTINameMap'
DRTI_Factories.hh:54: previous non-function declaration `template<class
DRTITypePtr> class DRTINameMap'
DRTI_Factories.hh:59: conflicts with function declaration `int DRTINameMap(...)
'
DRTI_Factories.hh:59: parse error before `<' token
DRTI_Factories.hh:59: only constructors take base initializers
DRTI_Factories.hh:59: confused by earlier errors, bailing out
make: *** [RegionInfo.lo] Error 1
// convenience template for mapping between handle and pointer
template<class DRTITypePtr>
class DRTIHandleMap : public hash_map<DRTI_Handle, DRTITypePtr> {
public:
DRTIHandleMap() : hash_map<DRTI_Handle, DRTITypePtr>() {}
};
I am certain that hash_map is being included. I know this because this was one of the original errors I was getting. To rectify, I simply modified set the CPPFLAG variable = -idirafter /usr/include/c++/3.2.2/ext since this is where hash_map resides.
Initially, I just simply tried -I/usr/include/c++/3.2.2/ext, but found that the build process was attempting to pull in unwanted headers. To further verify, I copied /usr/include/c++/3.2.2/ext/hash_map into /usr/include and changed the include from <hash_map> to "hash_map". Hence I saw the same afformentioned error.
I'm thinking there is some error in the method that hash_map is being called within the template class.
Doh! Think I have realised what is probably wrong and it is in your first post!
Code:
54 class DRTINameMap : public hash_map<const ... str_equal>
^^^^^^^
Problem
The compiler errror you get is typically due to a failure to recognise hash_map at whatever level.
The fact that the code compiles with gcc/++ 2.96 (as you mentioned and I overlooked) and not with 3.xx is, I think, due to the strict namespace scoping that came in between these versions. Compile the code below with 2.96 and 3.xx
Code:
#include <vector>
int main()
{
vector<int> V( 100 );
}
With 3.xx (it should fail) you need to bring vector into scope by typing "std::vector<int> V( 100 );" OR "using std vector;" OR "using namespace std;"
(The last one should be avoided in header files).
Code:
#include <ext/hash_map> // or whatever
class DRTINameMap : public std::hash_map<const ... >
^^^
To the best of my knowledge hash_map is not a required part of the standard library (hence the ext/) but I expect it is in namespace std.
It is probably best to leave the header where it is installed - it may be dependent on other headers in the same directory (unless, of course, you are supremely confident about this sort of thing!).
When I attempted your recommendation, I get an error saying that "hash_map" is not part of the standard. To ensure that it in fact compiled with the earlier gnu gcc tools, I installed multiple versions of the compiler. The 3.X version as well as the 2.9.5 version.
The 2.9.5 comipled just fine. This tells me that this is likely some configuration problem or something that the compiler introduced.
I'm wondering if there is some specification for extensions or something.
In the ...ext/hash_map header file, hash_map is declared in the __gnu_cxx namespace.
According to the libstdc++ documentation
Detailed Description
This namespace serves two purposes.
This namespace is used for two things:
* sequestering internal (implementation-only) names away from the global namespace; these are details of the implementation and should not be touched by users
* GNU extensions for public use
This is still fluid and changing rapidly. Currently the rule is: if an entitity is found in the user-level documentation, it falls into the second category
hash_map would fall under GNU extensions for public use.
The following compiles on gcc-3.2-7
Code:
#include <ext/hash_map>
int main()
{
__gnu_cxx::hash_map<char, int> hm;
}
Humble apologies for not checking the actual namespace before posting, lazy me.
Not that it is any consolation, but hash_map appears to be in namespace std in Visual C++ 7, although whether it actually belongs there is another question ... best left to those who keep a copy of The Standard under their pillow ;-)
Thanks a million. You definitely helped me to learn so much more about C++ and what I consider much of it's complexity. I went from C-language to Java. I had also posted a question to the gnu-gcc list. I got the following response which is nearly identical to yours:
5.4 Extensions and Backward Compatibility
Headers in the ext and backward subdirectories should be referred to by their relative paths:
#include <ext/hash_map>
rather than using -I or other options. This is more portable and forward-compatible. (The situation is the same as that of other headers whose directories are not searched directly, e.g., <sys/stat.h>, <X11/Xlib.h>.
The extensions are no longer in the global or std namespaces, instead they are declared in the __gnu_cxx namespace. For maximum portability, consider defining a namespace alias to use to talk about extensions, e.g.:
#ifdef __GNUC__
#if __GNUC__ < 3
#include <hash_map.h>
namespace Sgi { using ::hash_map; }; // inherit globals
#else
#include <ext/hash_map>
#if __GNUC_MINOR__ == 0
namespace Sgi = std; // GCC 3.0
#else
namespace Sgi = ::__gnu_cxx; // GCC 3.1 and later
#endif
#endif
#else // ... there are other compilers, right?
namespace Sgi = std;
#endif
Sgi::hash_map<int,int> my_map;
I would like to earnestly thank you regarding your help with this.
No worries - I definitely keep that preprocessor snippit in case I run into the same problem (especially as it also covers gcc 3.0 which I haven't used).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.