Неоднозначное определение оператора() с множественным наследованием
я компилирую этот код с помощью 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;
}
С учетом сказанного, весьма вероятно, что вы не должны использовать множественное наследование здесь.