This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

G++ Bug in finding template instanciation


The attached source doesn't compile, at least under Windows.
Apparently, the compiler is having trouble finding the template
function which takes the references to the nested class; unnest Iter,
and it works.

Compiler output:

-----------------------------------------------------------------------------
> g++ -v copytest.cc -o copytest
Reading specs from /Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/2.95/specs
gcc version 2.95 19990728 (release)
 /Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/2.95/cpp.exe -lang-c++ -v -iprefix /Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/2.95/ -D__GNUC__=2 -D__GNUG__=2 -D__GNUC_MINOR__=95 -D__cplusplus -Di386 -D_WIN32 -DWINNT -D_X86_=1 -D__STDC__=1 -D__stdcall=__attribute__((__stdcall__)) -D__cdecl=__attribute__((__cdecl__)) -D__declspec(x)=__attribute__((x)) -D__i386__ -D_WIN32 -D__WINNT__ -D_X86_=1 -D__STDC__=1 -D__stdcall=__attribute__((__stdcall__)) -D__cdecl=__attribute__((__cdecl__)) -D__declspec(x)=__attribute__((x)) -D__i386 -D__WINNT -Asystem(winnt) -Acpu(i386) -Amachine(i386) -D__EXCEPTIONS -remap -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -Di586 -Dpentium -D__i586 -D__i586__ -D__pentium -D__pentium__ -D__CYGWIN32__ -D__CYGWIN__ copytest.cc c:\tmp/ccWtcaaa.ii
GNU CPP version 2.95 19990728 (release) (80386, BSD syntax)
#include "..." search starts here:
#include <...> search starts here:
 /Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/2.95/../../../../../include/g++-3
 /Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/2.95/../../../../../include
 /Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/2.95/../../../../i586-cygwin32/include
 /Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/2.95/include
End of search list.
The following default directories have been omitted from the search path:
 /usr/include
End of omitted list.
 /Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/2.95/cc1plus.exe c:\tmp/ccWtcaaa.ii -quiet -dumpbase copytest.cc -version -o c:\tmp/ccINeaaa.s
GNU C++ version 2.95 19990728 (release) (i586-cygwin32) compiled by GNU C version 2.95 19990728 (release).
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/2.95/../../../../../include/g++-3/stl_algobase.h: In function `class basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > * __copy<Wrapper<basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > >::Iter, basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > *, ptrdiff_t>(Wrapper<basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > >::Iter, Wrapper<basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > >::Iter, basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > *, random_access_iterator_tag, ptrdiff_t *)':
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/2.95/../../../../../include/g++-3/stl_algobase.h:161:   instantiated from `__copy_dispatch<Wrapper<basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > >::Iter,basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > *,__false_type>::copy(Wrapper<basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > >::Iter, Wrapper<basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > >::Iter, basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > *)'
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/2.95/../../../../../include/g++-3/stl_algobase.h:188:   instantiated from `copy<Wrapper<basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > >::Iter, basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > *>(Wrapper<basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > >::Iter, Wrapper<basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > >::Iter, basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > *)'
copytest.cc:175:   instantiated from here
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/2.95/../../../../../include/g++-3/stl_algobase.h:138: no match for `Wrapper<basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > >::Iter & - Wrapper<basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > >::Iter &'
-----------------------------------------------------------------------------

Source.  Sorry if it is so long, but I don't want to take the risk of
doing anything to make the iterator invalid.  It's mostly pretty
trivial.  As mentioned above, if Iter is a separate template, not part
of Wrapper, it compiles and works as expected.

-----------------------------------------------------------------------------

#include <algorithm>
#include <iterator>
#include <string>
#include <stddef.h>

template< typename T >
class Wrapper
{
public:
    class Iter
    {
    public:
        typedef T const     value_type ;
        typedef ptrdiff_t   difference_type ;
        typedef T const*    pointer ;
        typedef T const&    reference ;
        typedef std::random_access_iterator_tag
                            iterator_category ;

        explicit            Iter( T const* a , int n ) ;

        T const&            operator*() const ;
        T const*            operator->() const ;
        T const&            operator[]( ptrdiff_t index ) const ;

        Iter&               operator++() ;
        Iter                operator++( int ) ;
        Iter&               operator+=( ptrdiff_t offset ) ;
        Iter&               operator--() ;
        Iter                operator--( int ) ;
        Iter&               operator-=( ptrdiff_t offset ) ;

        int                 compare( Iter const& other ) const ;
    private:
        T const*            array ;
        ptrdiff_t           index ;
    } ;

                        Wrapper( T const* array , int length ) ;
    Iter                begin() const ;
    Iter                end() const ;

private:
    T const*            myArray ;
    int                 myLength ;
} ;

template< typename T >
Wrapper<T>::Iter::Iter( T const* a , int n )
    :   array( a )
    ,   index( n )
{
}

template< typename T >
T const&
Wrapper<T>::Iter::operator*() const
{
    return array[ index ] ;
}

template< typename T >
T const*
Wrapper<T>::Iter::operator->() const
{
    return &array[ index ] ;
}

template< typename T >
T const&
Wrapper<T>::Iter::operator[]( ptrdiff_t index ) const
{
    return array[ index ] ;
}

template< typename T >
Wrapper<T>::Iter&
Wrapper<T>::Iter::operator++()
{
    ++ index ;
    return *this ;
}

template< typename T >
Wrapper<T>::Iter
Wrapper<T>::Iter::operator++( int )
{
    Wrapper<T>::Iter             result( *this ) ;
    operator++() ;
    return result ;
}

template< typename T >
Wrapper<T>::Iter&
Wrapper<T>::Iter::operator+=( int offset )
{
    index += offset ;
    return *this ;
}

template< typename T >
Wrapper<T>::Iter&
Wrapper<T>::Iter::operator--()
{
    -- index ;
    return *this ;
}

template< typename T >
Wrapper<T>::Iter
Wrapper<T>::Iter::operator--( int )
{
    Wrapper<T>::Iter                result( *this ) ;
    operator--() ;
    return result ;
}

template< typename T >
Wrapper<T>::Iter&
Wrapper<T>::Iter::operator-=( int offset )
{
    index -= offset ;
    return *this ;
}


template< typename T >
int
Wrapper<T>::Iter::compare( Wrapper<T>::Iter const& other ) const
{
    return index == other.index
        ?   true
        :   index > other.index
        ?   1
        :   -1 ;
}

template< typename T >
ptrdiff_t
operator-( Wrapper<T>::Iter const& op1 , Wrapper<T>::Iter const& op2 )
{
    return 5 ;
}

template< typename T >
Wrapper< T >::Wrapper( T const* array , int length )
    :   myArray( array )
    ,   myLength( length )
{
}

template< typename T >
Wrapper< T >::Iter
Wrapper< T >::begin() const
{
    return Iter( myArray , 0 ) ;
}

template< typename T >
Wrapper< T >::Iter
Wrapper< T >::end() const
{
    return Iter( myArray , 5 ) ;
}


int
main()
{
    std::string         init[] = { "1" , "2" , "3" , "4" , "5" } ;
    Wrapper< std::string >
                        src( init , 5 ) ;
    std::string         dst[ 5 ] ;
    std::copy( src.begin() , src.end() , dst ) ;
    for ( int i = 0 ; i < 5 ; ++ i ) {
        cout << dst[ i ] << '\n' ;
    }
    return 0 ;
}
-----------------------------------------------------------------------------

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]