Is a using-declaration supposed to hide an inherited virtual function?

旧巷老猫 提交于 2019-12-23 08:04:33

问题


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

the above code using gcc gives

level2
level1

but in icc gives

 level2
 level2

Which one is correct or is it undefined by standard?

Edit: This proves there is a bug for sure, consider the following main function

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 the same object when used directly produces different results and when used via a pointer of same type produces different results!!!


回答1:


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.




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/4669524/is-a-using-declaration-supposed-to-hide-an-inherited-virtual-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!