Pergunta

I have the case where I am deriving a class from two different base classes both having a static function with the same name.

To resolve this ambiguity, I tried to use the scope operator - just as I would do for a member function. However This does not compile. Why? Wrong syntax?

I want to call the static function via the derived typename and not directly via base class name. Actually I would like prefer to prevent this case, but I have no idea how to do so.

The error (commented out) in the code below also occurs, when I leave the templates away:

#include <iostream>

template<class TDerived>
class StaticBaseA
{
public:
    static void announce()
    {
        std::cout << "do something" << std::endl;
    }
};

template<class TDerived>
class StaticBaseB
{
public:
    static void announce()
    {
        std::cout << "do something else" << std::endl;
    }
};

class Derived :
      public StaticBaseA<Derived>
    , public StaticBaseB<Derived>
{
    using StaticBaseA<Derived>::announce;
};

class NonDerived {};

int main(int argc, char* argv[])
{
    Derived::announce();
    // What I want:
    //Derived::StaticBaseB<Derived>::announce(); Error: "Undefined symbol 'StaticBaseB'

    // What works, but what I don't want ...
    StaticBaseB<Derived>::announce();

    // ... because I would like to prevent this (however this is done):
    StaticBaseB<NonDerived>::announce();


    return 0;
}
Foi útil?

Solução

Making "announce" protected in StaticBaseA and StaticBaseB might be part-way to doing what you want.

You then could not call StaticBaseB<NonDerived>::announce from main as it would be inaccessible. You could call it from a class derived from StaticBaseB.

In other words:

template<class TDerived>
class StaticBaseA
{
protected:
   static void announce()
   {
       std::cout << "do something" << std::endl;
   }
};

template<class TDerived>
class StaticBaseB
{
protected:
   static void announce()
   {
       std::cout << "do something else" << std::endl;
    }
};

In Derived you have to promote "announce" to public.

class Derived : public StaticA<Derived>, public StaticB<Derived >
{
  public:
     using StaticA<Derived>::announce;
};

int main()
{
     Derived::announce(); // legal and calls StaticBaseA::announce
     NotDerived::announce(); // no such function
     StaticBaseA< Derived >::announce(); // not accessible
     StaticBaseB< Derived >::announce(); // also not accessible
     StaticBaseA< NotDerived >::announce(); // not accessible
     StaticBaseB< NotDerived >::announce(); // also not accessible
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top