TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #368 2.45K
ParamType - cv-квалифицированный параметр
#новичкам

Список постов по теме, Пост про слои

Рассмотрим вариант, когда ParamType - cv-квалифицированная ссылка. Тогда для вывода типа верхний уровень константности аргумента остается только в типе параметра функции, а шаблонный тип выводится без этой константности на верхнем уровне. Любую ссылочность типа аргумента функции мы игнорируем.

template <class T>  
void func(const T& param) {...}
// | |
// ParamType

int x = 42;
const int const_x = x;
const int& const_ref_x = x;
std::list<double> lst;

func(x); // T is int, ParamType is const int&
func(const_x); // T is int, ParamType is const int&
func(const_ref_x); // T is int, ParamType is const int&
func(lst); // T is std::list<double>, ParamType is const std::list<double>&
___________________________
template <class T>
void func1(const std::shared_ptr<T>& param) {...}
// | |
// ParamType

std::shared_ptr<double> ptr;
std::shared_ptr<const double> ptr_of_const;
const std::shared_ptr<const double>& const_ref_ptr_of_const;

func1(ptr); // T is double, param's type is const std::shared_ptr<double>&
func1(ptr_of_const); // T is const double, param's type is const std::shared_ptr<const double>&
func1(const_ref_ptr_of_const); // T is const double, param's type is const std::shared_ptr<const double>&


В случае func тип param всегда будет константной ссылкой, вопрос только на что. И это что-то и будет искомым шаблонным типом. И получается он путем отбрасывания константности и ссылочности от типа аргумента функции. Для const_x откидываем константность, для const_ref_x - и константность и ссылочность. Для x и lst типы выводятся без изменений.

Когда у нас в типе param появляется вложенность, то продолжаем обращаться к аналогии с капустой. Просто снимаем весь первый слой со всеми константностями и ссылочностями и оставшееся будет типом Т. На примерах все подписано.

ParamType - cv-квалифицированный указатель

Когда в статьях и книжках расписывают этот вариант, то очень часто отсылаются к такой форме параметра функции const T * param. И говорят, что в этом случае вывод типа шаблонного параметра мало отличается от случая cv-квалифицированных ссылок. И это действительно правда. С одним уточнением, что это указатель на константу, а не константный указатель.

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

template <class T>
void func(const T * param) {...}
// | |
// ParamType

int x = 42;
int * p_x = &x; // p_x is a ptr to x as int
int ** p_p_x = &p_x; // p_p_x is a ptr to a ptr to x as int
const int * p_const_x = &x; // p_const_x is a ptr to x as a const int
int * const const_p_x = &x; // const_p_x is a const ptr to x as int
const int * const const_p_const_x = &x; // const_p_const_x is a const ptr to x as const int

func(p_x); // T is int, param's type is const int*
func(p_const_x); // T is int, param's type is const int*
func(const_p_x); // T is int, param's type is const int*
func(const_p_const_x); // T is const int, param's type is const int *
func(p_p_x); // T is int *, param's type is int * const *


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

Теперь рассмотрим настоящие константные указатели.
  • 👍 11
  • 🔥 4
  • ❤ 3
  • 👎 1
More from @grokaemcpp
  1. Oct 14, 2026​​Что внутри std::condition_variable? #опытным Более менее все знакомы с примитивом синхро…
  2. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  3. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  4. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  5. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  6. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →