Почему я могу определить функцию, которая отличается константностью верхнего уровня некоторых ее параметров? - PullRequest
0 голосов
/ 06 апреля 2019

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

Так что в моем заголовке odd_even.h я написал:

    bool is_even(const int& x); // I used const ref. to avoid copy and unintentional modification of the argument.

И в источнике odd_even.cpp:

bool is_even(int& x) { 
    if (x = 1024) // some unintentional assinemnt (==) though modern compilers detect it.
        ; //some statement here
    //x = 1024; // or here another unintentional modification
    return !(x % 2) ? true : false; 
}

И программа драйвера:

int main(){

    int a{ 17 };
    std::cout << (a) << std::endl;

    std::cout << std::boolalpha << is_even(a) << endl;

    std::cout << (a) << std::endl;

    std::cout << std::endl;
}

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

Так есть ли обход этой ошибки, которая предотвращает такую ​​ошибку?

Ответы [ 2 ]

2 голосов
/ 06 апреля 2019

Это не должно компилироваться, как показано здесь

C ++ допускает перегрузку с помощью квалификаторов cv, когда параметр является указателем или ссылочным типом, таким образом, он является частью искаженного имени.

1 голос
/ 06 апреля 2019

Здесь нет top-level const:

bool is_even(const int& x); // 1
bool is_even(int& x); // 2

Выше 1 и 2 абсолютно разные сигнатуры: 1 - это функция, которая постоянно ссылается на int. Помните, что const здесь low-level not top-level Также помните, что ссылки не имеют констант верхнего уровня как факта, что они уже постоянны.

В вашем примере он компилируется и запускается нормально, потому что вы передаете неконстантный объект, который имеет отношение к сигнатуре 2. Однако, если вы передадите r-значение или оно не сможет связать. например:

std::cout << is_even(77) << std::endl; // link will fail because the 1 is not defined.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...