Неявное преобразование типов не видит соответствия базового класса. ошибка или особенность?

Похоже, мой компилятор (GCC 4.7) не выполняет неявное преобразование типов, если результирующий преобразованный тип допускает вызов функции из-за совпадения базового класса, то есть результата преобразования A это AB,

class AB {};

class A: public AB
{
public:
A(float i) {}
A() {}
A(const A& rhs) {}
A(A&& rhs) {}
};

AB operator*(const AB& lhs,const AB& rhs)
{
// Return default constructed AB
}

void foo() {
A a;
auto tmp = 2.0 * a;   // This fails because no conversion rule was found.
}

Это особенность языка C ++? Если да, то в какой ситуации лучше не сравнивать с базовым классом.

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

РЕДАКТИРОВАТЬ

c.cc:51:20: error: no match for ‘operator*’ in ‘2.0e+0 * a’
c.cc:51:20: note: candidate is: c.cc:42:1: note: AB operator*(const
AB&, const AB&) c.cc:42:1: note:   no known conversion for argument 1
from ‘double’ to ‘const AB&’ c.cc:51:20: error: unable to deduce
‘auto’ from ‘<expression error>’

2

Решение

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

Нет, но я скажу вам, что у плохого компилятора так много работы, и было бы слишком много для сравнения со всеми потенциальными производными классами (или другими преобразованиями через третьи типы)

Проблема в вашем коде не в вентиляционный от A в AB, что компилятор с удовольствием делает, но тот факт, что он не может конвертировать 2.0 для AB, Набор разрешенных преобразований ограничен и дает конечный набор работы. Когда вы звоните оператору, он находит совпадение, которое занимает два AB объекты, и он не знает, как напрямую преобразовать double в AB, Для вас очевидно, что это может создать A временный, а затем отстраненный от него, так как он упрекнул второй аргумент. Это не так очевидно для компилятора, который не знает, сколько потенциальных типов происходит от A (рассмотрите другие единицы перевода, скомпилированные отдельно) или даже несвязанные типы, которые могут быть созданы из double и есть операторы преобразования в AB

5

Другие решения

Стандарт C ++ предоставляет этот пример плохо сформированной программы с последовательностью преобразований, аналогичной приведенной в вашем коде. Смотрите §13.3.1:

class T {
public:
T();
};
class C : T {
public:
C(int);
};
T a = 1;  // ill-formed: T(C(1)) not tried.
2

По вопросам рекламы [email protected]