2010-11-18 5 views
5

Сегодня я обнаружил, что можно объявить функцию в заголовке с одной сигнатурой и реализовать ее в исходном файле с другой (аналогичной) сигнатурой. Например, например:Определение функции с различной подписью

// THE HEADER example.hpp 

#ifndef EXAMPLE_HPP 
#define EXAMPLE_HPP 

int foo(const int v); 

#endif 

// THE SOURCE FILE example.cpp 

#include "example.hpp" 

int foo(int v) // missing const 
{ 
    return ++v; 
} 

Это разрешено? Или это расширение компилятора (я использую g ++ 4.3.0)?

EDIT Я собираю с педантичным и максимально возможным уровнем предупреждения, и я до сих пор не получаю предупреждение или ошибку.

+0

Вы прочитали стандарт? – Abyx

ответ

12

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

Верхний уровень const влияет на тело функции. Он определяет, может ли параметр быть изменен в теле функции. Это то же самое, что и декларация.

Да, это законно, а декларация и определение относятся к одной и той же функции, а не к перегрузке.

Стандартная ссылка: 8.3.5 [dcl.fct]/3: "[...] Тип функции определяется с помощью следующих правил. [...] Любой cv-qualifier Изменение параметра тип ... удаляется. [0] cv-квалификаторы влияют только на определение параметра внутри тела функции, они не влияют на тип функции. [...] "

+0

+1 для «определителя уровня верхнего уровня». Вы не можете стать более ясными, чем это. –

+0

Отлично. Этот параграф даже отвечает на мой вопрос. –

5

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

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