Неоднозначное определение оператора() с множественным наследованием

я компилирую этот код с помощью 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 ответов


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

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

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

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

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


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

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


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

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

    return 0;
}

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