 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Luc Mazardo Guest
|
Posted: Thu Jan 22, 2004 4:06 pm Post subject: Compiling with g++ 3.0 |
|
|
The following code works with g++ 2.75 but
i've some troubles with compiling with g++ 3.0.
Thanks in advance if you have a solution.
Here is the error message.
main.hpp:28: specializing `struct std::hash<std::string>' in different
namespace
/usr/include/g++-v3/ext/stl_hash_fun.h:68: from definition of `template<class
_Key> struct std::hash'
make: *** [resource_identifier.lo] Error 1
#include <pair.h>
#include <string>
#include <map>
#include <vector>
#ifdef __GNUC__ /* grabbed in libstdc++ faq */
#if __GNUC__ < 3
#include
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
using namespace std;
//TODO: include this definition in the Hashtable class
template<> struct hash<string>
{
size_t operator()(const string& s) const
{
return hash<char const*>()(s.c_str());
}
};
#ifdef NAMESPACES
namespace foobar {
#endif
class NoSuchElementException
{
public:
NoSuchElementException(string w) {_what = w;}
virtual ~NoSuchElementException() {}
virtual string what() { return _what; }
private:
string _what;
};
template <class T> class Hashtable //: public ost::Conditional
{
public:
Hashtable() {} //: Conditional() {}
virtual ~Hashtable() {clear(); }
virtual T put(const string& key, T value)
{
assert(key.c_str() != NULL); //TODO: must throw ?
// enterMutex();
T returnValue = mHashtable[key];
mHashtable[key] = value;
// leaveMutex();
return returnValue;
}
virtual T get(const string& key) throw (NoSuchElementException)
{
assert(key.c_str() != NULL); //TODO: must throw ?
// enterMutex();
if (mHashtable.empty())
{
// leaveMutex ();
throw NoSuchElementException (key);
}
if (mHashtable.find(key) == mHashtable.end())
{
// leaveMutex();
throw NoSuchElementException(key);
}
T returnValue = mHashtable[key];
//leaveMutex();
return returnValue;
}
virtual void del(const string& key) throw (NoSuchElementException)
{
assert(key.c_str() != NULL); //TODO: must throw ?
// enterMutex();
if (mHashtable.find(key) == mHashtable.end()) {
// leaveMutex();
throw NoSuchElementException(key);
}
mHashtable.erase (key);
// leaveMutex();
return;
}
virtual void clear() {
// enterMutex();
mHashtable.erase(mHashtable.begin(), mHashtable.end());
// leaveMutex();
}
virtual bool isEmpty () {
bool ret;
// enterMutex();
ret = mHashtable.empty ();
// leaveMutex();
return ret;
}
virtual vector<pair toVector()
throw (NoSuchElementException)
{
vector <pair v;
// enterMutex();
if (mHashtable.empty()) {
// leaveMutex();
throw NoSuchElementException(string("hashtable is empty"));
}
for(hash_map<string, T , hash::iterator iter
= mHashtable.begin(); iter != mHashtable.end(); ++iter)
{
pair <string, T> p(*iter);// (iter->first, iter->second);
v.insert(v.begin(), p);
}
//leaveMutex();
return v;
}
protected:
hash_map<string, T, hash mHashtable;
};
int
main(void)
{
Hashtable<int> h;
return 0;
}
#ifdef NAMESPACES
}; // foobar
#endif
/** EMACS **
* Local variables:
* mode: c++
* c-basic-offset: 4
* End:
*/
Here is my release of g++ 3.0:
$ g++-3.0 -v
Reading specs from /usr/lib/gcc-lib/i386-linux/3.0.4/specs
Configured with: ../src/configure -v
--enable-languages=c,c++,java,f77,proto,objc
--prefix=/usr --infodir=/share/info --mandir=/share/mx
Thread model: posix
gcc version 3.0.4
Here is my release of g++ 2.95:
g++ -v
Reading specs from /usr/lib/gcc-lib/i386-linux/2.95.4/specs
gcc version 2.95.4 20011002 (Debian prerelease)
--
[email]Luc.Mazardo (AT) cvf (DOT) fr[/email]
|
|
| Back to top |
|
 |
Gianni Mariani Guest
|
Posted: Thu Jan 22, 2004 5:40 pm Post subject: Re: Compiling with g++ 3.0 |
|
|
Luc Mazardo wrote:
| Quote: | The following code works with g++ 2.75 but
i've some troubles with compiling with g++ 3.0.
Thanks in advance if you have a solution.
Here is the error message.
main.hpp:28: specializing `struct std::hash<std::string>' in different
namespace
/usr/include/g++-v3/ext/stl_hash_fun.h:68: from definition of `template<class
_Key> struct std::hash'
make: *** [resource_identifier.lo] Error 1
|
hash_map is not part of STL and so the gcc team ( in an effort to be
standards compliant) moved the hash* templates into the __gnu_cxx
namespace. The gcc 3.x series is also more standards compliant and so
you'll need to fix some gcc 2.9x things.
| Quote: |
#include <pair.h
^^^^^^^^ don't need this header - std::pair is found in std::map and |
pair.h is non-standard
| Quote: | #include
#include
#include
#ifdef __GNUC__ /* grabbed in libstdc++ faq */
#if __GNUC__ < 3
#include
namespace Sgi { using ::hash_map; }; // inherit globals
#else
#include
#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
using namespace std;
|
using namespace __gnu_cxx;
| Quote: |
//TODO: include this definition in the Hashtable class
namespace __gnu_cxx |
{
| Quote: | template<> struct hash<string
{
size_t operator()(const string& s) const
{
return hash
}
};
|
};
| Quote: |
#ifdef NAMESPACES
namespace foobar {
#endif
class NoSuchElementException
{
public:
NoSuchElementException(string w) {_what = w;}
virtual ~NoSuchElementException() {}
virtual string what() { return _what; }
private:
string _what;
};
template <class T> class Hashtable //: public ost::Conditional
{
public:
Hashtable() {} //: Conditional() {}
virtual ~Hashtable() {clear(); }
virtual T put(const string& key, T value)
{
assert(key.c_str() != NULL); //TODO: must throw ?
// enterMutex();
T returnValue = mHashtable[key];
mHashtable[key] = value;
// leaveMutex();
return returnValue;
}
virtual T get(const string& key) throw (NoSuchElementException)
{
assert(key.c_str() != NULL); //TODO: must throw ?
// enterMutex();
if (mHashtable.empty())
{
// leaveMutex ();
throw NoSuchElementException (key);
}
if (mHashtable.find(key) == mHashtable.end())
{
// leaveMutex();
throw NoSuchElementException(key);
}
T returnValue = mHashtable[key];
//leaveMutex();
return returnValue;
}
virtual void del(const string& key) throw (NoSuchElementException)
{
assert(key.c_str() != NULL); //TODO: must throw ?
// enterMutex();
if (mHashtable.find(key) == mHashtable.end()) {
// leaveMutex();
throw NoSuchElementException(key);
}
mHashtable.erase (key);
// leaveMutex();
return;
}
virtual void clear() {
// enterMutex();
mHashtable.erase(mHashtable.begin(), mHashtable.end());
// leaveMutex();
}
virtual bool isEmpty () {
bool ret;
// enterMutex();
ret = mHashtable.empty ();
// leaveMutex();
return ret;
}
virtual vector<pair toVector()
throw (NoSuchElementException)
{
vector <pair v;
// enterMutex();
if (mHashtable.empty()) {
// leaveMutex();
throw NoSuchElementException(string("hashtable is empty"));
}
for(hash_map<string, T , hash::iterator iter
|
Need to use typename - like this:
for(typename hash_map<string, T , hash::iterator iter
| Quote: | = mHashtable.begin(); iter != mHashtable.end(); ++iter)
{
pair <string, T> p(*iter);// (iter->first, iter->second);
v.insert(v.begin(), p);
}
//leaveMutex();
return v;
}
protected:
hash_map<string, T, hash mHashtable;
};
int
main(void)
{
Hashtable<int> h;
return 0;
}
#ifdef NAMESPACES
}; // foobar
#endif
/** EMACS **
* Local variables:
* mode: c++
* c-basic-offset: 4
* End:
*/
|
|
|
| Back to top |
|
 |
Donovan Rebbechi Guest
|
Posted: Thu Jan 22, 2004 5:55 pm Post subject: Re: Compiling with g++ 3.0 |
|
|
In article <bup1tt$d3 (AT) dispatch (DOT) concentric.net>, Gianni Mariani wrote:
| Quote: | Luc Mazardo wrote:
#include <pair.h
^^^^^^^^ don't need this header - std::pair is found in std::map and
pair.h is non-standard
|
For someone who wants to use pair and doesn't need map/multimap, the
Cheers,
--
Donovan Rebbechi
http://pegasus.rutgers.edu/~elflord/
|
|
| Back to top |
|
 |
Donovan Rebbechi Guest
|
Posted: Thu Jan 22, 2004 6:05 pm Post subject: Re: Compiling with g++ 3.0 |
|
|
In article <m0oesw55nv.fsf (AT) beepbeep (DOT) dev33.cvf>, Luc Mazardo wrote:
| Quote: | assert(key.c_str() != NULL); //TODO: must throw ?
|
This is a silly test. If s is a string, s.c_str() is never NULL,
because that function is guaranteed to return a valid ' '-terminated
c string.
Is there a reason why you're declaring all of those virtual member
functions ? It seems inappropriate for this class.
Cheers,
--
Donovan Rebbechi
http://pegasus.rutgers.edu/~elflord/
|
|
| Back to top |
|
 |
Bret Pehrson Guest
|
Posted: Thu Jan 22, 2004 6:45 pm Post subject: Re: Compiling with g++ 3.0 |
|
|
| Quote: | Is there a reason why you're declaring all of those virtual member
functions ? It seems inappropriate for this class.
|
Every non-private method should be virtual.
Donovan Rebbechi wrote:
| Quote: |
In article <m0oesw55nv.fsf (AT) beepbeep (DOT) dev33.cvf>, Luc Mazardo wrote:
assert(key.c_str() != NULL); //TODO: must throw ?
This is a silly test. If s is a string, s.c_str() is never NULL,
because that function is guaranteed to return a valid ' '-terminated
c string.
Is there a reason why you're declaring all of those virtual member
functions ? It seems inappropriate for this class.
Cheers,
--
Donovan Rebbechi
http://pegasus.rutgers.edu/~elflord/
|
--
Bret Pehrson
mailto:bret (AT) infowest (DOT) com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
|
|
| Back to top |
|
 |
Gianni Mariani Guest
|
Posted: Thu Jan 22, 2004 7:14 pm Post subject: Re: Compiling with g++ 3.0 |
|
|
Donovan Rebbechi wrote:
| Quote: | In article <bup1tt$d3 (AT) dispatch (DOT) concentric.net>, Gianni Mariani wrote:
Luc Mazardo wrote:
#include <pair.h
^^^^^^^^ don't need this header - std::pair is found in std::map and
pair.h is non-standard
|
gcc 3.4 (pre-release) reports it as a "non standard" header.
| Quote: |
For someone who wants to use pair and doesn't need map/multimap, the
utility> header. This header just defines std::pair and std::relops
|
That would be nice - I think the way to do this is to #include <utility>
... same
|
|
| Back to top |
|
 |
red floyd Guest
|
Posted: Thu Jan 22, 2004 7:44 pm Post subject: Re: Compiling with g++ 3.0 |
|
|
Bret Pehrson wrote:
| Quote: | Is there a reason why you're declaring all of those virtual member
functions ? It seems inappropriate for this class.
Every non-private method should be virtual.
|
I disagree. Consider the case where you have to do some common
startup/cleanup around a virtual function. I'd actually make the
virtual as a protected. See below. I'd argue that you don't want to
make Base::f() a virtual.
class Base
{
private:
void setup();
void cleanup();
protected:
virtual void do_work();
public:
void f()
{
setup();
do_work();
cleanup();
}
// other methods redacted
};
|
|
| Back to top |
|
 |
Donovan Rebbechi Guest
|
Posted: Thu Jan 22, 2004 8:08 pm Post subject: Re: Compiling with g++ 3.0 |
|
|
In article <40101A38.4D3CC57E (AT) infowest (DOT) com>, Bret Pehrson wrote:
| Quote: | Is there a reason why you're declaring all of those virtual member
functions ? It seems inappropriate for this class.
Every non-private method should be virtual.
|
That's another way of saying that every class (or at least every
container class) should be designed for extension via public inheritance.
What's your basis for this belief ? Or, if I've mischaracterised your
opinion, what is it about the hash map that makes it a better candidate
for subclassing than other classes, or other container classes ?
Note that the standard container classes do not use virtual methods. Why
not ? In your opinion, did the standards committee simply get it wrong ?
Since it is in your opinion advantageous to make these containers
subclassable, could you provide some good examples of useful derived classes ?
On to the problems of making methods virtual:
How do you write a "virtual" assignment operator ?
For example, what does this code do ?
HashBase h1;
HashDerived h2;
h1 = h2;
The problem is that you can treat a class like a "value" or a "reference".
"value" classes can be assigned to. Classes that are handled via reference
may be copyable, but you can't treat them as (assignable) values. You need
to wrap them in a "handle"/"envelope"/"pimpl" class to do that. Which adds
indirection.
Cheers,
--
Donovan Rebbechi
http://pegasus.rutgers.edu/~elflord/
|
|
| Back to top |
|
 |
Rolf Magnus Guest
|
Posted: Thu Jan 22, 2004 10:07 pm Post subject: Re: Compiling with g++ 3.0 |
|
|
Bret Pehrson wrote:
| Quote: | Is there a reason why you're declaring all of those virtual member
functions ? It seems inappropriate for this class.
Every non-private method should be virtual.
|
Heh, I've seen people write that every virtual function should be
private, and that makes more sense than what you write.
Anyway, may I ask what the reason for your above statement is?
|
|
| Back to top |
|
 |
David Harmon Guest
|
Posted: Thu Jan 22, 2004 10:16 pm Post subject: Re: Compiling with g++ 3.0 |
|
|
On Thu, 22 Jan 2004 19:44:41 GMT in comp.lang.c++, red floyd
<no.spam (AT) here (DOT) dude> was alleged to have written:
| Quote: | I disagree. Consider the case where you have to do some common
startup/cleanup around a virtual function. I'd actually make the
virtual as a protected.
|
If that is your reason, you should make the virtual function private.
You don't want subclasses calling it without the common startup/cleanup
any more than you want foreigners to do so.
|
|
| Back to top |
|
 |
tom_usenet Guest
|
Posted: Fri Jan 23, 2004 12:56 pm Post subject: Re: Compiling with g++ 3.0 |
|
|
On Thu, 22 Jan 2004 23:07:42 +0100, Rolf Magnus <ramagnus (AT) t-online (DOT) de>
wrote:
| Quote: | Bret Pehrson wrote:
Is there a reason why you're declaring all of those virtual member
functions ? It seems inappropriate for this class.
Every non-private method should be virtual.
Heh, I've seen people write that every virtual function should be
private, and that makes more sense than what you write.
Anyway, may I ask what the reason for your above statement is?
|
He has to be a troll, surely?
Tom
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
|
|
| Back to top |
|
 |
Bret Pehrson Guest
|
Posted: Thu Jan 29, 2004 12:23 am Post subject: Re: Compiling with g++ 3.0 |
|
|
Not a troll.
Let me maybe qualify my statement:
Resuable (non-template) classes should seriously consider all non-private
methods as virtual.
Reason for my statement: I'm tired of using class libraries that impose all
sorts of arbitrary restrictions because methods aren't virtual (but should be).
I'd rather that a class was needlessly loaded down w/ virtual methods than not.
tom_usenet wrote:
| Quote: |
On Thu, 22 Jan 2004 23:07:42 +0100, Rolf Magnus <ramagnus (AT) t-online (DOT) de
wrote:
Bret Pehrson wrote:
Is there a reason why you're declaring all of those virtual member
functions ? It seems inappropriate for this class.
Every non-private method should be virtual.
Heh, I've seen people write that every virtual function should be
private, and that makes more sense than what you write.
Anyway, may I ask what the reason for your above statement is?
He has to be a troll, surely?
Tom
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
|
--
Bret Pehrson
mailto:bret (AT) infowest (DOT) com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
|
|
| Back to top |
|
 |
Bret Pehrson Guest
|
Posted: Thu Jan 29, 2004 12:27 am Post subject: Re: Compiling with g++ 3.0 |
|
|
Why is do_work protected?
The **ONLY** reason that something should be declared protected is to indicate
that the class is suitable for derivation, and that method has some potential
value to the derived class.
red floyd wrote:
| Quote: |
Bret Pehrson wrote:
Is there a reason why you're declaring all of those virtual member
functions ? It seems inappropriate for this class.
Every non-private method should be virtual.
I disagree. Consider the case where you have to do some common
startup/cleanup around a virtual function. I'd actually make the
virtual as a protected. See below. I'd argue that you don't want to
make Base::f() a virtual.
class Base
{
private:
void setup();
void cleanup();
protected:
virtual void do_work();
public:
void f()
{
setup();
do_work();
cleanup();
}
// other methods redacted
};
|
--
Bret Pehrson
mailto:bret (AT) infowest (DOT) com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
|
|
| Back to top |
|
 |
Bret Pehrson Guest
|
Posted: Thu Jan 29, 2004 12:35 am Post subject: Re: Compiling with g++ 3.0 |
|
|
I'd be interested to hear why a virtual function should be private.
Let me expand a little: every (non-template) class that isn't expressly not
intended for derivation should by default have all non-private methods declared
virtual.
How many times have you used a class outside of your direct source manipulation
control (library or otherwise) that didn't have one or more virtual methods,
but that was suitable for derivation? Let's discuss the hacks that must be
used to attempt to overcome this in code...
Rolf Magnus wrote:
| Quote: |
Bret Pehrson wrote:
Is there a reason why you're declaring all of those virtual member
functions ? It seems inappropriate for this class.
Every non-private method should be virtual.
Heh, I've seen people write that every virtual function should be
private, and that makes more sense than what you write.
Anyway, may I ask what the reason for your above statement is?
|
--
Bret Pehrson
mailto:bret (AT) infowest (DOT) com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
|
|
| Back to top |
|
 |
lilburne Guest
|
Posted: Thu Jan 29, 2004 2:02 am Post subject: Re: Compiling with g++ 3.0 |
|
|
Bret Pehrson wrote:
| Quote: |
I'd rather that a class was needlessly loaded down w/ virtual methods than not.
|
The problem with virtual functions is that people can
override them in derived classes. Now sometimes this is a
good thing because people can specialize the behaviour for
the subclass in hand. Unfortunately they can also warp the
behaviour such that the overridden function does something
totally different from the original behaviour.
The more you refuse to fix a classes hierarchies behaviour
by making the functions virtual the more scope you allow for
the above mistake to occur. By making the entire behaviour
of your class hierarchy fluid the less confidence you have
that the subclasses are indeed homogenous.
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|