Посібники виведення шаблону - це шаблони, пов'язані з класом шаблону, які повідомляють компілятору, як перевести набір аргументів конструктора (та їх типи) у параметри шаблону для класу.
Найпростіший приклад - це std::vector
та його конструктор, який бере пару ітераторів.
template<typename Iterator>
void func(Iterator first, Iterator last)
{
vector v(first, last);
}
Компілятор повинен зрозуміти, що vector<T>
«s T
типу буде. Ми знаємо, яка відповідь; T
повинно бути typename std::iterator_traits<Iterator>::value_type
. Але як ми можемо сказати компілятору без необхідності вводити текст vector<typename std::iterator_traits<Iterator>::value_type>
?
Ви використовуєте керівництво по відрахуванню:
template<typename Iterator> vector(Iterator b, Iterator e) ->
vector<typename std::iterator_traits<Iterator>::value_type>;
Це повідомляє компілятору, що коли ви викликаєте vector
конструктор, що відповідає цьому шаблону, він виведе vector
спеціалізацію, використовуючи код праворуч від ->
.
Вам потрібні вказівки, коли відрахування типу з аргументів не базується на типі одного з цих аргументів. Ініціалізація a vector
з initializer_list
явно використовує vector
's T
, тому йому не потрібен посібник.
Ліва сторона не обов'язково вказує фактичний конструктор. Це працює так, що якщо ви використовуєте відрахування конструктора шаблону для типу, він збігається з аргументами, які ви передаєте проти всіх напрямків відрахувань (фактичні конструктори первинного шаблону надають неявні напрямні). Якщо є збіг, він використовує це, щоб визначити, які аргументи шаблону надати типу.
Але як тільки це вирахування буде зроблено, як тільки компілятор з’ясує параметри шаблону для типу, ініціалізація для об’єкта цього типу триває так, ніби нічого з цього не сталося. Тобто обраний напрямок відрахування не повинен відповідати вибраному конструктору .
Це також означає, що ви можете використовувати напрямні з агрегатами та ініціалізацією агрегатів:
template<typename T>
struct Thingy
{
T t;
};
Thingy(const char *) -> Thingy<std::string>;
Thingy thing{"A String"};
Отже, напрямки відрахувань використовуються лише для з’ясування типу, який ініціалізується. Фактичний процес ініціалізації працює точно так само, як і раніше, як тільки це було зроблено.