Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 | страница 17



2. Если после отбрасывания ссылочной части >expr является >const, это также игнорируется. Игнорируется и модификатор >volatile (объекты >volatile являются редкостью и в общем случае используются только при реализации драйверов устройств; детальную информацию на эту тему вы найдете в разделе 7.6.)

Таким образом, получаем следующее:

>int x = 27;        // Как и ранее

>const int cx = x;  // Как и ранее

>const int& rx = x; // Как и ранее

>f(x);              // Типами и Т, и param являются int

>f(cx);             // Типами и Т, и param вновь являются int

>f(rx);             // Типами и Т, и param опять являются int

Обратите внимание, что даже несмотря на то, что >cx и >rx представляют константные значения, >param не является >const. Это имеет смысл. >param представляет собой объект, который полностью независим от >cx и >rx, — это копия>cx или >rx. Тот факт, что >cx и >rx не могут быть модифицированы, ничего не говорит о том, может ли быть модифицирован >param. Вот почему константность >expr (как и >volatile, если таковой модификатор присутствует) игнорируется при выводе типа >param: то, что >expr не может быть модифицировано, не означает, что таковой должна быть и его копия.

Важно понимать, что >const>volatile) игнорируются только параметрами, передаваемыми по значению. Как мы уже видели, для параметров, которые являются ссылками или указателями на >const, константность >expr при выводе типа сохраняется. Но рассмотрим случай, когда >expr представляет собой >const-указатель на константный объект, а передача осуществляется по значению:

>template

>void f(Т param);        // param передается по значению


>const char* const ptr = // ptr - константный указатель на

> "Fun with pointers";   // константный объект


>f(ptr);                 // Передача arg типа const char* const

Здесь >const справа от звездочки объявляет >ptr константным: >ptr не может ни указывать на другое место в памяти, ни быть обнуленным. (>const слева от звездочки гласит, что >ptr указывает на то, что (строка символов) является const, а следовательно, не может быть изменено.) Когда >ptr передается в функцию >f, биты, составляющие указатель, копируются в >param. Как таковой сам указатель (ptr) будет передан по значению. В соответствии с правилом вывода типа при передаче параметров по значению константность >ptr будет проигнорирована, а выведенным для >param типом будет >const char*, т.е. изменяемый указатель на константную строку символов. Константность того, на что указывает