Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: nested class of a template class

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?

like image 629
Vahagn Avatar asked Nov 03 '10 22:11

Vahagn


People also ask

Can class template be nested?

Member templates that are classes are referred to as nested class templates. Member templates that are functions are discussed in Member Function Templates. Nested class templates are declared as class templates inside the scope of the outer class. They can be defined inside or outside of the enclosing class.

Can template class inherit?

Inheriting from a template classIt is possible to inherit from a template class. All the usual rules for inheritance and polymorphism apply. If we want the new, derived class to be generic it should also be a template class; and pass its template parameter along to the base class.

Can templates be used for classes?

A template is not a class or a function.

How do I inherit a nested class?

To use inheritance in the inner class, consider the below code snippet. In the above example, Class B inherits from A and the inner class of B inherits from the inner class of A. Then the class methods of Parent' Inner class are called from the child's inner class object.


1 Answers

typename A<T>::B

Here, T is in a nondeduced context, which means that T cannot be deduced from the function argument.

The problem is that in the general case, there is a potentially infinite number of possible types T that could match. Consider, for example, if instead of struct B { }; you had typedef int B;.

like image 93
James McNellis Avatar answered Sep 19 '22 18:09

James McNellis