Ondrej Brablc wrote in
news:b8**************************@posting.google.c om:
Hi all,
I have this template which does not compile with "Compaq C++ V6.5-004
for OpenVMS Alpha V7.3-1" and Comeau C/C++ 4.3.3. This looks like
there must really be error in the code:
#include <map>
template <class Key, class T, class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T> > >
class map_of_objects : public std::map<Key, T, Compare, Allocator>
{
typedef typename std::map<Key, T, Compare, Allocator> parent_tpl;
public:
typedef Key key_type;
typedef typename Allocator::size_type size_type;
typedef typename parent_tpl::iterator iterator;
size_type erase(const key_type& x)
{
iterator i = *find(x);
This should be:
iterator i = this->find(x);
if (i != end())
if (i != this->end())
or
if (i != parent_tpl::end())
{
delete *i;
}
parent_tpl::erase(x);
}
};
It compiles fine in Borland C++ 5.5 and Compaq C++ V6.2-048 for
OpenVMS Alpha V7.3. I do not understand why end() is undefined and
find() is defined. There must be something I really miss. This problem
can be solved by using "this->end()" or "using parent_tpl end;".
However, I still do not understand what I am doing wrong.
You're not telling the compiler that end() is a dependant name.
The compilers that compile this are not *fully* conforming with the
C++ Standard.
A "dependant name" is a name (identifier) that is dependant on 1 or
more template paramiters. In this case since std::map<Key, T, Compare,
Allocator> (i.e. parent_tpl) depends on template paramiters, then its
members are dependant on template paramiters.
The conforming compilers implement 2-phase name lookup. When they first
encounter your template declaration's they check them, including looking
up all the identifiers that they encounter. The reason an error wasn't
given for find( x ) is its paramiter 'x', since 'x' is of dependant type
then clearly the find in 'find( x )' is a dependant name, so the compiler
doesn't try to look it up.
Consider:
template < typename T >
stuct X
{
void dependant_name();
};
template < typename T >
stuct X< T * > // partial specialization
{
void dependant_name();
};
template < typename T >
struct Y : X< T >
{
void non_pointers()
{
dependant_name();
}
};
Also the following is included later (at global scope):
void dependant_name();
Then:
int main()
{
Y< int * > y;
y.non_pointers();
}
Note that above, in main(), the call y.non_pointers() is an error,
but the non-conforming compilers compile it and call the global
dependant_name(), which has *nothing* to do with the templates X<>
and Y<>.
The conforming compilers should complain that the identifier
dependant_name in Y<>::non_pointers() hasn't been declared.
HTH (and wasn't to long winded).
Rob.
--
http://www.victim-prime.dsl.pipex.com/