【问题标题】:C++ multiple inheritance static function call ambiguityC++多继承静态函数调用歧义
【发布时间】:2014-01-29 14:57:04
【问题描述】:

我从两个不同的基类派生一个类,这两个基类都有一个同名的静态函数。

为了解决这种歧义,我尝试使用范围运算符 - 就像我对成员函数所做的那样。但是,这不会编译。 为什么?语法错误?

我想通过派生类型名而不是直接通过基类名调用静态函数。其实我更想阻止这种情况,但我不知道该怎么做。

当我离开模板时,以下代码中的错误(已注释掉)也会发生:

#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;
}

【问题讨论】:

  • 看起来您正在寻找某种模板专业化。说“我想要什么”的那句话没有真正的意义。你想让它叫什么?
  • 好吧,如果我有一个成员函数,范围运算符将是:obj.StaticBaseB::announce() - 我想要那个但没有对象。
  • 我下面的答案是否有效(在基类模板中将 public 更改为 protected)

标签: c++ templates multiple-inheritance


【解决方案1】:

StaticBaseAStaticBaseB 中“宣布”protected 可能是做你想做的事的一部分。

然后您就无法从 main 调用 StaticBaseB&lt;NonDerived&gt;::announce,因为它将无法访问。您可以从派生自 StaticBaseB 的类中调用它。

换句话说:

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;
    }
};

在 Derived 中,您必须向公众宣传“公告”。

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
}

【讨论】:

  • 是的,但是我不能再访问 Derived::announce() 了。
  • 保护基类的 'announce()' 并在派生类中声明 'using' 指令 'public' 不起作用:'StaticBaseA::announce()' 是在 main 函数中不可访问。据我了解,此次促销是不可能的。
  • 你不应该在 main 中调用 'StaticBaseA::announce,你调用 Derived::announce() 转发到 StaticBaseA 而 StaticBaseB::announce 根本无法访问
  • 有趣:促销适用于某些编译器(clang++ 3.1、g++ 4.7.1)和一些不适用(bcc32 5.82、g++ egcs-2.91.57 (cygwin)、)
  • 有趣:该提升适用于某些编译器(clang++ 3.1、g++ 4.7.1、vc10,但也适用于 g++ -std=c++98)。但是,一些较旧的编译器无法编译它(bcc32 5.82,g++ egcs-2.91.57 (cygwin)) - 所以整个事情只是一个已经修复的编译器错误。谢谢,现金牛!
猜你喜欢
  • 2011-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多