Friday, March 4, 2011

Can the "using" declaration be used with templates?

Is it possible to use the "using" declaration with template base classes? I have read it isn't here but is that because of a technical reason or is it against the C++ standard, and does it apply to gcc or other compilers? If it is not possible, why not?

Example code (from the link above):

struct A {
    template<class T> void f(T);
};

struct B : A {
    using A::f<int>;
};
From stackoverflow
  • What you linked to is a using directive. A using declaration can be used fine with templated base classes (haven't looked it up in the standard, but just tested it with a compiler):

    template<typename T> struct c1 { 
        void foo() { std::cout << "empty" << std::endl; } 
    }; 
    
    template<typename T> struct c2 : c1<T> { 
        using c1<T>::foo; 
        void foo(int) { std::cout << "int" << std::endl; } 
    }; 
    
    int main() { 
        c2<void> c;
        c.foo();
        c.foo(10); 
    }
    

    The compiler correctly finds the parameter-less foo function because of our using-declaration re-declaring it into the scope of c2, and outputs the expected result.

    Edit: updated the question. here is the updated answer:

    The article is right about that you are not allowed to use a template-id (template name and arguments). But you can put a template name:

    struct c1 { 
        template<int> void foo() { std::cout << "empty" << std::endl; } 
    }; 
    
    struct c2 : c1 { 
        using c1::foo; // using c1::foo<10> is not valid
        void foo(int) { std::cout << "int" << std::endl; } 
    }; 
    
    int main() { 
        c2 c;
        c.foo<10>();
        c.foo(10); 
    }
    
    Konrad Rudolph : This is something else. The OP probably meant a member function template residing in the base class.
    Sydius : Sorry, I'm new to the using thing. Is it possible to call foo from within a c2 method without having to specify the base class, ie "foo()" instead of "c1::foo()"?
    Johannes Schaub - litb : Sydius, yes you do this->foo(); the foo is in the baseclass, and that one depends on a template parameter. the standard says the call has to be qualified either with the scope operator (c1::foo()) or using this->foo();. otherwise it assumes "foo" is a global function

0 comments:

Post a Comment