C ++ - Перегрузка конструктора - частный и общедоступный
-
22-07-2019 - |
Вопрос
Можете ли вы сказать мне, почему следующий код выдает мне следующую ошибку - вызов перегруженного "C(int)" неоднозначен
Я бы подумал, что, поскольку C (char x) является закрытым, снаружи виден только C (float) ctor, и это должно быть вызвано путем преобразования int в float .
Но это не тот случай.
class C
{
C(char x)
{
}
public:
C(float t)
{
}
};
int main()
{
C p(0);
}
Решение
Это обсуждается в "Эффективном C ++". Скотт Мейер. Причина этого неоднозначна в том, что они хотели убедиться, что простое изменение видимости элемента не изменит значения уже существующего кода в другом месте.
В противном случае, предположим, что ваш класс C был где-то в заголовке. Если у вас есть частный член C (int), код, который вы предоставляете, будет называться C (float). Если по какой-то причине член C (int) стал общедоступным, старый код неожиданно вызвал бы этот член, даже если ни старый код , ни вызываемая им функция не изменились .
РЕДАКТИРОВАТЬ: больше причин:
Еще хуже, предположим, у вас были следующие 2 функции:
C A::foo()
{
return C(1.0);
}
C B::bar()
{
return C(1.0);
}
Эти две функции могут вызывать разные функции в зависимости от того, был ли foo или bar объявлен в качестве друга C, или A или B наследуются от него. идентичный код вызывает разные функции, это страшно.
(Возможно, это не так хорошо, как обсуждение Скотта Мейера, но это идея.)
Другие советы
0 - это int
Тип.Поскольку он может быть неявно приведен либо к float, либо к char одинаково, вызов неоднозначен. Видимость не имеет значения для этих целей.
Либо положить 0.0
, 0.
, или 0.0f
, или избавиться от C(char)
конструктор целиком.
Редактировать:Соответствующая часть стандарта, раздел 13.3:
3) [...] Но как только функции-кандидаты и списки аргументов определены, выбор наилучшей функции одинаков во всех случаях:
- Сначала выбирается подмножество функций—кандидатов - тех, которые имеют надлежащее количество аргументов и удовлетворяют некоторым другим условиям, — чтобы сформировать набор жизнеспособных функций (13.3.2).
- Затем выбирается наилучшая жизнеспособная функция на основе неявных последовательностей преобразования (13.3.3.1), необходимых для сопоставления каждого аргумента с соответствующим параметром каждой жизнеспособной функции.
4) Если наилучшая жизнеспособная функция существует и уникальна, разрешение перегрузки выполняется успешно и выдает ее в качестве результата.В противном случае разрешение перегрузки завершается неудачей, и вызов неверно сформирован.Когда разрешение перегрузки завершается успешно, а наилучшая жизнеспособная функция недоступна (пункт 11) в контексте, в котором она используется, программа неправильно сформирована.
Обратите внимание, что видимость не является частью процесса выбора.
Я так не думаю:
C p(0);
преобразуется в:
C(float t)
вам, вероятно, нужно сделать:
C p(0.0f);