C ++: вложенный класс шаблона класса

Рассмотрим следующий код:

template < typename T >
struct A
{
    struct B { };
};

template < typename T >
void f( typename A<T>::B ) { }

int main()
{
    A<int>::B x;
    f( x );         // fails for gcc-4.1.2
    f<int>( x );    // passes
    return 0;
}

Итак, здесь gcc-4.1.2 требует явного указания аргумента шаблона f . Соответствует ли это стандарту? Исправлена ​​ли эта проблема в новых версиях GCC? Как избежать явного указания int при вызове f ?

Обновление: Вот обходной путь.

#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>

template < typename T >
struct A
{
    typedef T argument;
    struct B { typedef A outer; };
};

template < typename T >
void f( typename A<T>::B ) { }

template < typename Nested >
void g( Nested )
{   
    typedef typename Nested::outer::argument TT;
    BOOST_STATIC_ASSERT( (boost::is_same< typename A<TT>::B, Nested >::value) );
}

struct NN 
{
    typedef NN outer;
    typedef NN argument;
};

int main()
{
    A<int>::B x;
    NN y;
    g( x );  // Passes
    g( y );  // Fails as it should, note that this will pass if we remove the type check
    f( x );  // Fails as before

    return 0;
}

Однако я все еще не понимаю, почему call f (x); недействителен. Можете ли вы сослаться на какой-то пункт стандарта, в котором говорится, что такой вызов должен быть недействительным? Можете ли вы привести пример, в котором такой вызов неоднозначен?

14
задан Vahagn 6 November 2010 в 12:30
поделиться