forward reference to class template - template param not in scope

I'm seeing what look like buggy results from the compiler where it chokes on the use of a T<X>& to a declared but undefined class template T (a forward reference), iff the fwd reference is to a dependent type name (e.g. X is a template parameter).

Looks rather like a 2-phase name lookup bug of some kind - an area where the compiler has had conformance issues with the C++ Standard.

Here is a file I wrote that reproduces the problem as simply as possible:

template <class OuterT>
struct Grog
{
    template <class InnerT>
    struct Foo;  // forward reference

    template <class InnerT>
    struct Bar
    {
        // class template Foo<> is declared but not yet defined

        Bar(Foo<int>&);  // Foo<int> is not a dependent type name; compiles OK

        Bar(Foo<InnerT>&);  // Foo<InnerT> is a dependent type name
        //..fails to compile
        //..the compiler errors caused by compiling this line are reported for the line below
    };

    template <class InnerT>
    struct Foo
    {
        Foo(OuterT&)
        //..error C2143: syntax error : missing ')' before '&'
        //..    see reference to class template instantiation 'Grog<OuterT>::Foo<InnerT>' being compiled
        //..    see reference to class template instantiation 'Grog<OuterT>' being compiled
        //..error C2143: syntax error : missing ';' before '&'
        //..error C2059: syntax error : ')'
        //..error C2146: syntax error : missing ';' before identifier 'makeBar'
        //..error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
        //..error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
        //..warning C4183: 'makeBar': missing return type; assumed to be a member function returning 'int'

        // it's choking on 'OuterT' - unrecognized, although it ought to be in scope here

        Bar<InnerT> makeBar(); 
        // the fwd reference (above) is needed because we return an object of type Bar<> here
        // thus it would be impossible to define Foo<> before Bar<>
    };
};

This is very inconvenient -- totally debilitating in fact, for my code -- is there a work-around




Answer this question

forward reference to class template - template param not in scope

  • coolVijay

    The typedef workaround is working for me. I don't get the error everywhere I expected to, it's peculiar how localized the bug is -- I can't figure out what its modality is. But so far I only had to change one typedef (and lots of references).

    Thanks much for your speedy reply!  :-)

    -dc


  • VB_Devil

    I've seen something similar, but I thought it was fixed in Whidbey. I don't really see what this has to do with two-phase name lookup. Anyway, it's typically good enough to add a typedef for the template type parameter.

    -hg

  • Kerryrob

    It's not fixed (in the final release of Visual C++ 2005 Express).

    BTW sorry about the missing ';' in the code I pasted -- here is the code I actually meant!

    The typedef workaround does seem to work for this simple example anyway. I will let you know if I get away with it after adding (many) typedefs to my much larger real-world project.

    struct Grog
    {
        template <class InnerT>
        struct Foo;  // forward reference

        template <class InnerT>
        struct Bar
        {
            // class template Foo<> is declared but not yet defined

            Bar(Foo<int>&);  // Foo<int> is not a dependent type name; compiles OK

            Bar(Foo<InnerT>&);  // Foo<InnerT> is a dependent type name
            //..fails to compile
            //..the compiler errors caused by compiling this line are reported for the line below
        };

        typedef OuterT OuterTypeSynonym;

        template <class InnerT>
        struct Foo
        {
            Foo(OuterT&);
            //..error C2143: syntax error : missing ')' before '&'
            //..    see reference to class template instantiation 'Grog<OuterT>::Foo<InnerT>' being compiled
            //..    see reference to class template instantiation 'Grog<OuterT>' being compiled
            //..error C2143: syntax error : missing ';' before '&'
            //..error C2059: syntax error : ')'

            // it's choking on 'OuterT' - unrecognized, although it ought to be in scope here
            // change OuterT to OuterTypeSynonym and it compiles
            // strangely, even when the typedef occurs after the fwd reference

            Bar<InnerT> makeBar(); 
            // the fwd reference (above) is needed because we return an object of type Bar<> here
            // thus it would be impossible to define Foo<> before Bar<>
        };
    };

  • forward reference to class template - template param not in scope