considere el siguiente código:C++: clase anidada de una clase de plantilla
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;
}
Así que aquí gcc-4.1.2 requiere el argumento de plantilla de f
a especificar de forma explícita. ¿Es este el estándar? ¿Las versiones más nuevas de GCC tienen este problema solucionado? ¿Cómo puedo evitar especificar explícitamente int
al llamar al f
?
Actualización: Aquí hay una solución.
#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;
}
Sin embargo, todavía no puedo ver por qué llaman f(x);
no es válido. ¿Puedes referirte a algún punto en el estándar que dice que tal llamada debería ser inválida? ¿Puedes traer un ejemplo donde esa llamada es ambigua?
Gracias por su respuesta. ¿Por qué 'T' no se puede deducir del argumento de la función? ¿Puedes traer un ejemplo donde hay dos tipos para 'T' que coinciden con una llamada particular de' f'? ¿Quiere decir que para otra especialización de 'A' podría ser otro' typedef int B; 'en lugar de' struct B {}; '? No puedo ver por qué en este caso la llamada de 'f' debe ser ambigua. – Vahagn