Что такое шаблоны вывода и когда мы должны их использовать?

Стандарт C ++ 17 вводит «руководство по выводу шаблона». Я полагаю, что они имеют какое-то отношение к новому выводу аргументов шаблона для конструкторов, представленному в этой версии стандарта, но я еще не видел простого объяснения в стиле FAQ того, чем они являются и для чего.

  • Что такое инструкции по выводу шаблонов в C ++ 17?

  • Зачем (и когда) они нам нужны?

  • Как мне их объявить?

61

Решение

Руководства по выводу шаблона — это шаблоны, связанные с классом шаблона, которые сообщают компилятору, как преобразовать набор параметров (и их типы) в аргументы шаблона.

Самый простой пример — это 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 специализация с использованием кода справа ->,

Вам нужны руководства, когда вычет типа из аргументов не основан на типе одного из этих аргументов. Инициализация vector из initializer_list явно использует vector«s Tтак что это не нуждается в руководстве.

Левая сторона не обязательно указывает конструктор. Это работает так: если вы используете дедукцию конструктора шаблона для типа, он сопоставляет аргументы, передаваемые вами, со всеми руководствами по дедукции (фактические конструкторы основного шаблона предоставляют неявные направляющие). Если есть совпадение, он использует это, чтобы определить, какие аргументы шаблона следует предоставить типу.

Но как только этот вывод сделан, как только компилятор вычисляет параметры шаблона для типа, инициализация для объекта этого типа происходит так, как будто ничего из этого не произошло. То есть выбранное руководство по удержанию не обязательно должно соответствовать конструктор выбран.

Это также означает, что вы можете использовать направляющие с агрегатами и инициализацией агрегатов:

template<typename T>
struct Thingy
{
T t;
};

Thingy(const char *) -> Thingy<std::string>;

Thingy thing{"A String"}; //thing.t is a `std::string`.

Таким образом, инструкции по выводу используются только для определения инициализируемого типа. Фактический процесс инициализации работает точно так же, как и раньше, после того, как это определение было сделано.

65

Другие решения

Вот пример использования руководства по выводам, которое я использовал для упрощения построения прокси-объекта в шаблоне прокси. Надеюсь, что это может дать вам некоторые идеи простейшие вещи, которые мы можем сделать с помощью современного C ++
Руководства по выводам, которые я использовал:

ProxyContainer(vector<string>&) -> ProxyContainer<<vector<string>, string>;

ProxyContainer(int*) -> ProxyContainer<<vector<int>, int>;
-3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector