Вопрос

Можете ли вы сказать мне, почему следующий код выдает мне следующую ошибку - вызов перегруженного "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);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top