Следующая программа отвергается 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);};
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);};
Я не совсем уверен, правильно ли я понял правила поиска в разделе 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
Результирующий набор является недопустимым набором, и поэтому программа имеет неверный формат.
Мне интересно, почему программа отвергается так рано. В этом случае компилятору должно быть легко выполнить разрешение перегрузки, потому что обе функции имеют одинаковые имена, но разные сигнатуры, поэтому реальной двусмысленности нет. Есть ли техническая причина, по которой это не делается, или есть другие причины, которые могут принять неправильные программы? Кто-нибудь знает причину столь раннего отказа от этих программ?
Error 4 error C3861: 'foo': identifier not found s:\epsitec\testco\testco.cpp 21 1 testco Error 3 error C2385: ambiguous access of 'foo' s:\epsitec\testco\testco.cpp 21 1 testco
- person Jabberwocky   schedule 22.12.2015string
не инициализирован? - person Ziezi   schedule 22.12.2015std_string
, например, наchar*
, результат будет таким же. - person Jabberwocky   schedule 22.12.2015A
нет функцииfoo
-> тогда поиск имени должен попытаться найтиfoo
в базовых классах-> находит две функции с именемfoo
, следовательно, возникает ошибка неоднозначности? , что означает, что разрешение перегрузки находится в работе. - person Angelus Mortis   schedule 22.12.2015using Astring;
раньше, станет еще интереснее - person Ziezi   schedule 22.12.2015