为什么程序被拒绝为模糊的,可以通过重载解决? [英] Why is a program rejected as ambiguous that could be resolved by overload resolution?

查看:271
本文介绍了为什么程序被拒绝为模糊的,可以通过重载解决?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下程序被gcc拒绝为不明确的:

The following program is rejected by gcc as ambiguous:

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

Clang始终拒绝该程序,原因同上:

Clang consistently rejects the program for the same reason:

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

我不完全确定我是否正确理解第10.2节中的查找规则,计算查找集S(foo,A)的规则如下:

I am not completely sure if I understood the lookup rules in section 10.2 correctly, so I am going through the rules in the following steps to compute the lookup set 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

结果集是无效集,

我想知道为什么程序被如此早的拒绝。在这种情况下编译器应该很容易做重载分辨率,因为两个函数具有相同的名称但不同的签名,因此没有真正的歧义。有没有技术原因,这是没有做,或有其他原因,将接受不正确的程序?有没有人知道这么早就拒绝这些程序的决定背后的理由?

I am wondering why the program is being rejected so early. It should be easy for the compiler to do overload resolution in this case because both functions have identical names but different signatures, so there is no real ambiguity. Is there a technical reason that this is not done, or are there other reasons which would accept incorrect programs? Does anybody know the rational behind the decision to reject these programs so early?

推荐答案

在C ++中,跨范围没有重载 - 派生类范围不是此一般规则的例外。请参考更多细节。
无论如何,您的示例可以通过指定要使用两个版本的foo通过使用关键字。请参阅下面的示例。

In C++, there is no overloading across scopes – derived class scopes are not an exception to this general rule .Please refer for more detail. Anyway your example can be improved by specifying that you want to use both version of foo by "using" keyword. See below example.

示例程序

#include <iostream>
#include <string>

struct Aint 
{
     void foo(int){std::cout<<"\n Aint";}
};

struct Astring 
{
     void foo(std::string){std::cout<<"\n Astring";}
};

struct A: public Aint, public Astring {
    using Aint::foo;
    using Astring::foo;
    };

int main()
{
  std::string s;

  A a;
 a.foo(s);

  return 0; 
}
output:Astring

这篇关于为什么程序被拒绝为模糊的,可以通过重载解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆