Как заставить компилятор знать, какую перегрузку функции вызывать, чтобы избежать неоднозначности?
У меня есть код, приведенный ниже, и я не понимаю, почему именно компилятор не может определить конструктор, который будет использоваться при создании экземпляра класса D. Я удалил как копировать, так и переместить конструктор, поэтому единственной альтернативой будет использование A(Base&)
Есть ли способ сказать компилятору использовать конструктор A(Base&), кроме приведения *this к Base&.
class Base {};
class A
{
private:
Base& m_b;
public:
A(Base& b) :m_b(b) {}
A(const A&) = delete;
A(A&&) = delete;
};
class D : public Base, public A
{
public:
D():A(*this){}
};
int main()
{
D();
}
Я получаю следующую ошибку:
main.cpp: In constructor 'D::D()':
main.cpp:17:16: error: call of overloaded 'A(D&)' is ambiguous
D():A(*this){}
^
main.cpp:10:5: note: candidate: A::A(const A&) <deleted>
A(const A&) = delete;
^
main.cpp:9:5: note: candidate: A::A(Base&)
A(Base& b) :m_b(b) {}
2 ответа
Вы можете привести указатель перед разыменованием:
D() :A(*(Base*)this) {}
или же
D() :A(*static_cast<Base*>(this)) {}
Добавить актерский состав:
D():A(static_cast<Base&>(*this)){}
Это заставит выражение иметь тип, соответствующий желаемой перегрузке.
Простое удаление функции или c'tor не удаляет ее из набора перегрузок, поэтому вы видите неоднозначность. Это только заставит компилятор рассматривать программу как плохо сформированную, если функция когда-либо будет выбрана из всех доступных перегрузок.