Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested templates gcc compiler 4.1.2 error

I'm trying to create a template class to insulate the users from a data type. I would have preferred to use an adapter class, but the function signatures needed to change requiring a template.

In the code sample below(not the actual project just a simplified version to illustrate the problem), while in the main routine I'm able to use the ob_traits interface. But when I attempt to create the templated StructWrapper which uses the ob_traits as a base class, I get errors and gcc doesn't recognize the IntAdapter class created. This compiles on MSVC 8.0 but fails on gcc 4.1.2 20070626 ( Red hat 4.1.2-14)

So two questions first, do you understand why the compile fails with the errors specified below?

Second, any suggestions on how to implement this concept in a more simple manner?

    #include <iostream>

    template <typename T >
    struct ob_traits
    {
        ob_traits( T& param ) { value = param; };
        T value;
    };

    struct GeneralStructure
    {
        int a;
        GeneralStructure(int param):a(param){}
    };

    struct DifferentStructure
    {
        GeneralStructure hidden;
        DifferentStructure( int param ):hidden(param){};
    }
    ;

    /*template< typename T > struct ob_traits
    {
    };
    */
    template<> struct ob_traits< GeneralStructure >
    {
        struct IntAdapter
        {
            IntAdapter( GeneralStructure& valueParam ):value(valueParam){}
            GeneralStructure value;
            int& getValue() { return value.a; };
        };
    };

    template<> struct ob_traits< DifferentStructure >
    {
        struct IntAdapter
        {
            IntAdapter( DifferentStructure& valueParam):value( valueParam ){}
            DifferentStructure value;
            int& getValue( ){ return value.hidden.a; };
        };
        void dump()
        {
            DifferentStructure testLocal(44);
            IntAdapter local( testLocal );
            std::cout << local.getValue()<<std::endl;
        }
    };

    template <typename T > struct StructWrapper:public ob_traits< T >
    {
        StructWrapper(){};
    /*main.cpp:60: error: 'IntAdapter' was not declared in this scope
    main.cpp:60: error: expected `;' before 'inner'
    main.cpp:60: error: 'inner' was not declared in this scope
    */
        void dumpOuter(const T& tempParam) { IntAdapter inner(tempParam); inner.dump(); };
    /*
    main.cpp: In member function 'void StructWrapper<T>::dumpOuterFailsAsWell(const T&)':
    main.cpp:66: error: expected `;' before 'inner'
    main.cpp:66: error: 'inner' was not declared in this scope
    */
        void dumpOuterFailsAsWell(const T& tempParam) { ob_traits<T>::IntAdapter inner(tempParam); inner.dump(); };
    };

    int main(int argc, char* argv[])
    {
        GeneralStructure dummyGeneral(22);
        ob_traits<struct GeneralStructure >::IntAdapter test(dummyGeneral);
        DifferentStructure dummyDifferent(33);
        ob_traits<struct DifferentStructure >::IntAdapter test2(dummyDifferent);
        std::cout << "GeneralStructure: "<<test.getValue()<<std::endl;
        std::cout << "DifferentStructure: "<<test2.getValue()<<std::endl;
        ob_traits<struct DifferentStructure > test3;
        test3.dump();
    std::cout << "Test Templated\n";
    return 0;
    }

1 Answers

dumpOuter fails because IntAdapter needs to be qualified (as in the referenced question). dumpOuterFailsAsWell fails because GCC does parsing of this code,even though it's not complete, and so it needs to know it's a type that you mean:

void dumpOuterWorks(const T& tempParam) 
{ 
   typename ob_traits<T>::IntAdapter inner(tempParam); 
   inner.dump(); 
}

Without typename here, GCC will assume that IntAdapter is an identifier, and will expect you to be forming an expression rather than a variable declaration.

Also note that you do not have to put semicolons after method bodies!

like image 95
Sunlight Avatar answered Aug 07 '26 08:08

Sunlight



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!