Неоднозначное определение оператора () с множественным наследованием - PullRequest
8 голосов
/ 28 января 2011

Я компилирую этот код с помощью GCC (4.2.1 Apple build 5664)

#include <cstddef>

using std::size_t;

template <char I> struct index { };

struct a
{
    void operator()(size_t const &) { }
};

struct b
{
    template <char I>
    void operator()(index<I> const &) { }
};

struct c: public a, public b { };

int main (int argc, char const *argv[])
{
    c vc;
    vc(1);

    return 0;
}

и выдайте мне следующую ошибку:

main.cpp: In function ‘int main(int, const char**)’:
main.cpp:22: error: request for member ‘operator()’ is ambiguous
main.cpp:14: error: candidates are: template<char I> void b::operator()(const index<I>&)
main.cpp:9:  error:                 void a::operator()(const size_t&)

Я не понимаю, почему этот код неоднозначен; два метода имеют разные подписи.

Ответы [ 3 ]

6 голосов
/ 28 января 2011

Изменить c таким образом:

struct c: public a, public b
{
    using a::operator();
    using b::operator();
};

C ++ (до C ++ 0x) довольно неудобен в наследовании функций: если вы предоставляете функцию с тем же именем функции базового класса, она скрывает функции базового класса.

Похоже, что наследование от двух классов имеет ту же проблему.

// ищу стандарт ...

6 голосов
/ 28 января 2011

Разрешение имени выполняется до разрешения перегрузки.
В c нет operator(), поэтому компилятор ищет operator() в своих базовых классах и находит один в a, а другой в b, что делает имя неоднозначным (разрешение перегрузки не выполняется). 1007 *

Если вы хотите устранить неоднозначность имени, вы можете явно позвонить a::operator(): vc.a::operator()(1);

1 голос
/ 28 января 2011

Это неоднозначно, потому что вы передаете целочисленную константу, которая (предположительно) может быть приведена к типу std::size_t или index.Измените main на следующее, и оно должно разрешиться:

int main (int argc, char const *argv[])
{
    c vc;
    vc(static_cast<std::size_t>(1));

    return 0;
}

С учетом вышесказанного весьма вероятно, что вам не следует использовать множественное наследование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...