Вывод шаблона класса С++ (P0091R0) для аргументов функции

В С++ 17 мы можем делать что-то вроде

std::pair p = {1,3}; // compiler deduces template parameters to pair<int,int>

Из документации в cppreference Я понимаю, что следующее НЕ будет работать:

template<class T1, class T2>
void bar(std::pair<T1,T2>)
{}
void foo()
{
   bar({1,3}); // No deduction of pair template arguments
}

Может ли кто-нибудь подтвердить это и дать некоторое представление, почему это не сработает? Технически это должно работать, не так ли? Проводилось ли какое-либо обсуждение этой работы, или это какая-то надзор?

Ответы

Ответ 1

Ссылка правильная. Вычисление аргумента шаблона для шаблонов классов, принятое в настоящее время, применяется исключительно к объявлениям (и явным преобразованиям типов, которые определены в терминах объявлений), в [dcl.type.class.deduct]:

Если заполнитель для выведенного типа класса появляется как спецификатор decl в спецификаторе-спецификаторе-seq простейшего объявления, init-declarator этого объявления должен иметь вид

Объявление-идентификатор атрибута-спецификатора-seq opt

Заполнитель заменяется типом возврата функции, выбранной с помощью разрешения перегрузки для вычитания шаблона шаблона (13.3.1.8). Если список init-declarator содержит более одного init-declarator, тип, который заменяет местозаполнитель, должен быть одинаковым в каждом вычете. [Пример:

template<class T> struct container {
    container(T t) {}
    template<class Iter> container(Iter beg, Iter end);
};

template<class Iter>
container(Iter b, Iter e) -> container<typename std::iterator_traits<Iter>::value_type>;

std::vector<double> v = { /* ... */};
container c(7);                          // OK, deduces int for T
auto d = container(v.begin(), v.end());  // OK, deduces double for T
container e{5, 6};                       // error, int is not an iterator

-end пример]

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