У меня есть функция типа void f (строки… объект)

позволяют использовать эти две функции одновременно как различную функцию, так как они действительно отличаются от того, «может ли параметр быть написан или нет». Интуитивно это должно быть!

Перегрузка функций основана на параметрах, предоставляемых вызывающим. Здесь верно, что вызывающий может предоставить значение const или не const, но по логике он не должен иметь никакого значения для функциональности, предоставляемой вызываемой функцией. Рассмотрим:

f(3);
int x = 1 + 2;
f(x);

Если f() делает разные вещи в каждой из этих ситуаций, это будет очень запутанным! Программист этого кода, вызывающий f(), может иметь разумное ожидание одинакового поведения, свободно добавляя или удаляя переменные, которые передают параметры без его недействительности программы. Это безопасное, разумное поведение является отправной точкой, которую вы хотели бы оправдать исключениями, и действительно есть одно поведение может варьироваться , когда перегруженная функция ala:

void f(const int&) { ... }
void f(int&) { ... }

Итак, я думаю, это то, что вы находите неинтуитивным: что C ++ обеспечивает более «безопасность» (принудительное согласованное поведение посредством поддержки только одной реализации) для не-ссылок, чем ссылки.

Причины Я могу подумать:

  • Поэтому, когда программист знает, что параметр non const& будет иметь более длительный срок службы, они могут выбрать оптимальную реализацию. Например, в приведенном ниже коде может быть быстрее вернуть ссылку на член T в F, но если F является временным (что может быть, если компилятор соответствует const F&), то a - требуется возврат значения. Это все еще довольно опасно, так как вызывающий должен знать, что возвращаемая ссылка действительна только в том случае, если параметр находится вокруг.
    T f(const F&);
    T& f(F&);    // return type could be by const& if more appropriate
  • распространение таких классификаторов, как const (f16)

    Здесь некоторые (предположительно F member-) переменная типа T экспонируются как const или не- const на основе const -значения параметра при вызове f(). Этот тип интерфейса может быть выбран, если вы хотите расширить класс с помощью нечленов-функций (чтобы сохранить минимальный класс или при написании шаблонов / algos, используемых на многих классах), но идея аналогична функции const-члена, например vector::operator[](), где вы хотите, чтобы v[0] = 3 разрешался на векторе не const, но не на const.

    Когда значения принимаются по значению, они выходят за пределы области при возврате функции, поэтому нет действительного сценария, связанного с возвратом ссылки на часть параметра и желанием распространить его квалификаторы.

    Взлом поведения, которое вы хотите

    Учитывая правила ссылок, вы можете использовать их для получите нужное поведение - вам просто нужно быть осторожным, чтобы случайно изменить параметр «не-константа-ссылка», поэтому для неконстантных параметров может потребоваться следующая практика:

    T f(F& x_ref)
    {
        F x = x_ref;  // or const F is you won't modify it
        ...use x for safety...
    }
    

    Последствия перекомпиляции

    Не говоря уже о том, почему язык запрещает перегрузку на основе const параметр по значению, возникает вопрос, почему он не настаивает на согласованности const -ness в декларации и определении.

    Для f(const int) / f(int) ... если вы объявляют функцию в файле заголовка, тогда лучше не включать квалификатор const, даже если последующее определение в файле реализации будет иметь его. Это связано с тем, что во время обслуживания программист может захотеть удалить квалификатор ... удаление его из заголовка может вызвать бессмысленную перекомпиляцию клиентского кода, поэтому лучше не настаивать на том, чтобы они хранились в синхронизации, - и действительно, поэтому компилятор не делает этого, t создает ошибку, если они отличаются. Если вы просто добавили или удалили const в определении функции, то это близко к реализации, где читатель кода может заботиться о константе при анализе поведения функции. Если у вас есть const как в заголовке, так и в файле реализации, тогда программист хочет сделать его не const и забывает или решает не обновлять заголовок, чтобы избежать перекомпиляции клиента, тогда он более опасен, чем другой способ вокруг, как это возможно, программист будет иметь версию const из заголовка в виду, пытаясь проанализировать текущий код реализации, приводящий к неправильным рассуждениям о поведении функции. Это все очень проблема тонкой поддержки - это действительно актуально для коммерческого программирования, но в основе этого лежит руководство не использовать const в интерфейсе. Кроме того, это более кратким, чтобы опустить его из интерфейса, что лучше для программистов-клиентов, читающих ваш API.

0
задан MByD 2 August 2012 в 14:03
поделиться