为什么程序被拒绝为可以通过重载解析解决的模糊不清?

Jen*_*ens 9 c++ language-lawyer name-lookup

以下程序被gcc拒绝为含糊不清的:

struct Aint 
{
    virtual void foo(int);
};

struct Astring 
{
    virtual void foo(std::string);
};

struct A: public Aint, public Astring {};

int main()
{
  std::string s;

  A a;
  a.foo(s);

  return 0; 
}

> vt.cpp: In function ‘int main()’: vt.cpp:13:9: error: request for
> member ‘foo’ is ambiguous
>        a.foo(s);
>          ^ vt.cpp:5:34: note: candidates are: virtual void Astring::foo(std::__cxx11::string)
>      struct Astring {virtual void foo(std::string);};
>                                   ^ vt.cpp:4:31: note:                 virtual void Aint::foo(int)
>      struct Aint {virtual void foo(int);};
Run Code Online (Sandbox Code Playgroud)

由于同样的原因,Clang一直拒绝该计划:

clang -std=c++1y -c vt.cpp 

vt.cpp:13:9: error: member 'foo' found in multiple base classes of different types
      a.foo(s);
        ^
vt.cpp:4:31: note: member found by ambiguous name lookup
    struct Aint {virtual void foo(int);};
                              ^
vt.cpp:5:34: note: member found by ambiguous name lookup
    struct Astring {virtual void foo(std::string);};
Run Code Online (Sandbox Code Playgroud)

我不完全确定我是否正确理解了第10.2节中的查找规则,因此我将按照以下步骤中的规则来计算查找集S(foo,A):

1. A does not contain `foo`, so rule 5 applies and S(foo, A) is initially empty. We need to calculate the lookup sets S(foo, Aint) and S(foo, Afloat) and merge them to S(foo, A) = {}
2. S(foo, Aint) = {Aint::foo}
3. S(foo, Afloat) = {Afloat::foo}
4. Merge S(foo, Aint) = {Aint::foo} into S(foo, A) = {} to get S(foo, A) = {Aint::foo} (second case of 6.1)
5. Merge S(foo, Afloat) = {Afloat::foo} into {Aint::foo}. This create an ambiguous lookup set because of rule 6.2
Run Code Online (Sandbox Code Playgroud)

结果集是无效集,因此程序格式错误.

我想知道为什么这么早就被拒绝了.在这种情况下,编译器应该很容易进行重载解析,因为两个函数具有相同的名称但签名不同,因此没有真正的歧义.是否存在技术原因导致未执行此操作,或者是否存在其他可接受错误程序的原因?是否有人知道这么早就拒绝这些计划的决定背后的理性?

SAC*_*YAL 3

在 C++ 中,跨作用域不存在重载\xe2\x80\x93 派生类作用域也不例外。请参阅了解更多详细信息。\n无论如何,可以通过指定要使用两个版本来改进您的示例foo 通过“using”关键字。请参见下面的示例。

\n\n

示例程序:

\n\n
#include <iostream>\n#include <string>\n\nstruct Aint \n{\n     void foo(int){std::cout<<"\\n Aint";}\n};\n\nstruct Astring \n{\n     void foo(std::string){std::cout<<"\\n Astring";}\n};\n\nstruct A: public Aint, public Astring {\n    using Aint::foo;\n    using Astring::foo;\n    };\n\nint main()\n{\n  std::string s;\n\n  A a;\n a.foo(s);\n\n  return 0; \n}\noutput:Astring\n
Run Code Online (Sandbox Code Playgroud)\n