TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #397 4.21K
​​ParamType - не ссылка и не указатель
#новичкам

Список постов по теме

template <class T>
void func(T param) {...}

func(expression);


В при такой форме параметра шаблонной функции, который в данном случае не является ни ссылкой, ни указателем, мы имеем дело с передачей аргумента по значению. Все как с нешаблонными функциями.

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

Есть кстати распространенное заблуждение или недоговаривание, что при передаче объекта в функцию по значению происходит копирование. Это не совсем правда. Вызывается конструктор объекта на основе переданного параметра. А вот какой именно конструктор вызовется - copy или move - определяется типом ссылочности аргумента. Передадут lvalue - вызовется copy ctor, передадут rvalue reference - вызовется move ctor. Короткий пример:

struct Test {
Test() = default;
Test(const Test& other) {
std::cout << "Copy ctor" << std::endl;
}
Test(Test&& other) {
std::cout << "Move ctor" << std::endl;
}
};

template<class T>
void fun(T t) {
std::cout << "Hello, subscribers!!!" << std::endl;
}

int main () {
Test t;
fun(t);
fun(std::move(t))
}


Copy ctor
Hello, subscribers!!!
Move ctor
Hello, subscribers!!!


Как видим, при передаче аргумента через std::move происходит вызов мув конструктора.

Кстати, недавно дошел до очень простого объяснения мув-семантики и всего, что вокруг нее вертиться. Буквально за один пост все поймут всё про нее. Если хотите такой пост - жмакайте кита)

Вернемся к шаблонам

Как в этой ситуации выводится шаблонный тип?

Если у типа expression есть верхняя ссылочность/константность/волатильность - все в мусорку, оставшееся - тип Т.

int x = 42;
const int cx = x;
const int& rx = x;
const int * const px = &x;

func(x); // T's and param's types are both int
func(cx); // T's and param's types are again both int
func(rx); // T's and param's types are still both int
func(px); // T's and param's types are const int*


Обратите внимание: хотя cx и rx представляют константные значения, param не является константой. В этом есть смысл. param — это объект, полностью независимый от cx и rx, копия cx или rx. Тот факт, что cx и rx не могут быть изменены, ничего не говорит о том, можно ли изменять param. Вот почему константность expression игнорируется при определении типа параметра: то, что expression не может быть изменено, не означает, что его копия не может быть изменена.

С указателем похожая история: он как бы копируется в функцию. В функции уже другой указатель - param - и он не обязан быть сам по себе константным. И согласно правилам вывода типов, таковым и не является.

Если шаблонный параметр немного сложнее - например, тип Т вложен в другой шаблонный тип, то возвращаемся к нашей капусте. Снимаем столько слоев с типа expression, сколько явно определено для типа param - и это будет тип Т. Аргумент передается также по значению.

template <class T>
void func(std::vector<T> param) {...}

std::vector<int> vec;
const std::vector<int> const_vec;

func(vec); // T is int, param's type is std::vector<int>
func(const_vec); // T is int, param's type is std::vector<int>


На этом мы заканчиваем рассматривать мажорные кейсы видов шаблонных параметров функций. Дальше будем какие-то менее встречающиеся примеры рассматривать.

Be independent subject. Stay cool.

#cppcore #template
  • 🐳 83
  • 👍 10
  • 🔥 3
  • ❤ 2
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 →