Consider the following code:
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;
}
So here gcc-4.1.2 requires the template argument of f
to be explicitly specified. Is this meet the standard? Does the newer versions of GCC have this issue fixed? How can I avoid explicitly specifying int
while calling f
?
Update: Here is a workaround.
#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;
}
However, I still can't see why call f( x );
is invalid. Can you refer to some point in the standard which says such call should be invalid? Can you bring an example where such call is ambiguous?
T
cannot be deduced from the function argument? Can you bring an example where there are two types forT
which match for one particular call off
? Do you mean, that for another specialization ofA
it could be anothertypedef int B;
instead ofstruct B {};
? I can't see why in this case the call off
should be ambiguous. – Oscillation