Frage

struct level0
{
  virtual void foo() = 0;
};

struct level1 : level0
{
  virtual void foo() { cout <<" level1  " << endl; }
};

struct level2 : level1
{
  virtual void foo() { cout <<" level2 " << endl; }
};

struct level3 : level2
{
  using level1::foo;
};

int main()
{
  level1* l1 = new level3;
  l1->foo();
  level3 l3;
  l3.foo();
  return 0;
}

Der obige Code gcc gibt

level2
level1

aber in icc gibt

 level2
 level2

Welches ist richtig, oder ist es nicht definiert durch Standard?

Edit: Dies beweist, gibt es einen Fehler sicher, betrachten die folgende Hauptfunktion

int main()
{
    level3 l3;
    l3.foo();               // This prints level1

    level3* pl3 = &l3;
    pl3->foo();             // This prints level2

    level3& rl3 = l3;
    rl3.foo();              // This prints level1

    level3& rpl3 = *pl3;
    rpl3.foo();             // This prints level2

    return 0;
}

So das gleiche Objekt, wenn direkt verwendet unterschiedliche Ergebnisse, und wenn über einen Zeiger gleichen Typs verwendet zu unterschiedlichen Ergebnissen !!!

War es hilfreich?

Lösung

An example in Standard section 10.3p2 makes it clear that using declarations do not override virtual functions.

This is a known g++ bug.

As you noticed, when calling the member function via a reference or pointer, rather than a case in which the dynamic type is known, the bug does not happen.

Andere Tipps

using level1::foo; introduces a foo function in level3 class which refers to level1::foo.

In a using-declaration used as a member-declaration, the nested-name-specifier shall name a base class of the class being defined. Such a using-declaration introduces the set of declarations found by member name lookup.

However, since level1::foo is virtual, I guess that by calling it you should call level2::foo, thus icc should be right.

I'm not so sure, anyway.

The way to get level1 level1 of course would be:

struct level3 : level2
{
   virtual void foo() { level1::foo(); }
};

Your "using" directive seems to be informing the compiler that if you have a level3 and call foo on it, it should invoke the level1 version, but it is not overwriting this to the v-table.

gcc looks wrong because of the inconsistency, not sure about icc because I don't know what the standard indicates.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top