Эффективный и современный С++. 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*
, т.е. изменяемый указатель на константную строку символов. Константность того, на что указывает