TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #14 3.08K
CTAD - Class Template Argument Deduction

Одним из приятных нововведений C++ 17 стандарта стало автоматическое выведение типа классов при объявлении шаблонных объектов, функций и т.д.

Этот механизм позволяет вам явно не указывать тип аргументов шаблонных классов там, где они могут быть выведены компилятором. Пример:
// vector declaration before C++17
std::vector<double> v1 = {1.0, 2.0, 3.0};

// CTAD vector declaration since C++17
std::vector v2 = {1.0, 2.0, 3.0};


Давайте посмотрим на живой пример. Обратите внимание, что в строке параметров компилятора указан 17 стандарт -std=c++17. Если его попробовать переключить на более ранний стандарт -std=c++14, то возможность компиляции будет утрачена.

Ключевым моментом CTAD для компилятора является возможность вывести этот тип. Если при попытке выведения появляется несколько кандидатов, то попытка выведения типа приведет к ошибке. Пример:
// Error: no viable constructor or deduction guide for deduction of template arguments of 'vector'
std::vector data = {1.0, 2.0, 3, 4};

В данном случае тип передаваемых значений различен: double и int. Компилятор не будет брать на себя ответственность выбирать какой-то тип самостоятельно. Вдруг это принципиально важно для корректности исполнения ваших программ?

Однако, так же стоит и помнить про неожиданные эффекты CTAD. При инициализации из одного аргумента типа, который является специализацией рассматриваемого шаблона класса, вывод копирования обычно предпочтительнее переноса по умолчанию:
// The type is std::vector<int>
std::vector v1{1, 2};

// The type is std::vector<int>
std::vector v2{v1};

// The type is std::vector<std::vector<int>>
std::vector v3{v1, v2};


Компилятор дает большее предпочтение конструкторам initializer-list, но при list-initialization остается неизменным:
// The type is std::vector<int>
std::vector v1{1, 2};

// The type is std::vector<int>
std::vector v2(v1.begin(), v1.end());

// The type is std::vector<std::vector<int>::iterator>
std::vector v3{v1.begin(), v1.end()};


Подробнее: cppreference

#cpp17
  • 👍 18
  • ❤ 6
  • 🔥 3
More from @grokaemcpp
  1. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  2. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  3. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  4. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  5. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  6. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
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 →