Undefined end() in extended map template

Discussion in 'C++' started by Ondrej Brablc, Nov 24, 2003.

  1. 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);
    if (i != 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.

    Ondrej
    Ondrej Brablc, Nov 24, 2003
    #1
    1. Advertising

  2. Ondrej Brablc wrote in
    news::

    > 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/
    Rob Williscroft, Nov 24, 2003
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Neo Geshel
    Replies:
    2
    Views:
    3,573
    Versteijn
    Aug 18, 2004
  2. William
    Replies:
    2
    Views:
    1,716
    Kevin Spencer
    Jun 1, 2005
  3. Mantorok Redgormor
    Replies:
    70
    Views:
    1,734
    Dan Pop
    Feb 17, 2004
  4. VK
    Replies:
    45
    Views:
    581
    Dr John Stockton
    Sep 12, 2006
  5. -Lost
    Replies:
    13
    Views:
    359
    Richard Cornford
    Jan 31, 2007
Loading...

Share This Page