указатели константы в разрешении перегрузки

GCC рассматривает эти два объявления функции как эквивалентные:

void F(int* a) { }
void F(int* const a) { }

test.cpp: В функции 'освобождают F (интервал*)':

тест cpp:235: ошибка: переопределение 'пустого F (интервал*)'

тест cpp:234: ошибка: 'освободите F (интервал*)' ранее определенный здесь

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

То, что я задаюсь вопросом, - то, где (если вообще где-нибудь) в стандарте говорится, что нормально специфически отбрасывать спецификаторы на указателях, используемых в качестве аргументов функции в целях разрешения перегрузки.

(Моя реальная проблема - то, что я хотел бы выяснить, где GCC разделяет эти бессмысленные спецификаторы внутренне, и так как C++ frontend GCC замусорен комментариями, ссылающимися на стандарт, соответствующий раздел стандарта мог бы помочь мне найти корректное пятно.)

5
задан Dan Olson 23 January 2010 в 01:01
поделиться

4 ответа

Стандарт говорит в 8.3,5 / 3, что для целей определения типа функции любые CV-квалификаторы, которые напрямую исключают тип параметра. Я Это буквально говорит, что функция, объявленная как

void foo(int *const a);

, имеет тип функции void (int *) .

Педантический человек может утверждать, что это не является достаточно окончательно, чтобы утверждать, что вышеуказанная декларация должна соответствовать определению, подобному этому

void foo(int *a)
{
}

или что он должен сделать код с двойной декларацией (как в вашем примере) плохо сформирован, Поскольку ни одна из этих понятий не описан в стандарте в условиях типов функций .

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

На самом деле, в 13,1 / 3 он имеет «примечание», в котором говорится, что декларации функций с эквивалентными объявлениями параметров (как определено в 8.3.5), объявляем ту же функцию . Но это просто нота, это не нормативно, что говорит о том, что где-то в стандарте должен быть какой-то нормативный текст по той же проблеме.

4
ответ дан 13 December 2019 в 22:07
поделиться

Я думаю, что это в основном, как это запрещено, как это:

void foo(int a) {}
void foo(const int a) {}

const на не ссылаются не участвует в перегрузке.

На самом деле вы можете даже объявить

void foo(int a);

и более позднюю очередь

void foo(const int a) {}

, где постоянность является чисто деталей реализации, которую вызывающий абонент не заботится.

3
ответ дан 13 December 2019 в 22:07
поделиться

Это так же, как:

void foo(int);
void foo(const int);

- одинаково для абонента. Это потому, что функция состоит в том, чтобы получить копию по значению, независимо от того, что, поэтому абонент не заботится, если это считается const или нет; Это не имеет значения для этого.

Это не Юридическое для компилятора игнорировать такие вещи, но нет разницы в разрешении перегрузки. const применяется к реализации функции.

Незаконное было бы, если компилятор лечится:

void foo(int i)
{
    i = 5; // good
}

void foo(const int)
{
    i = 5; // lolwut?
}

то же самое, игнорируя const .

2
ответ дан 13 December 2019 в 22:07
поделиться

Я считаю, что все наоборот. Любой указатель, даже неконстантный, можно рассматривать как const :).

1
ответ дан 13 December 2019 в 22:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: