Руководства по пользовательскому выводу в C ++ 20 - PullRequest
3 голосов
/ 13 июля 2020

Я работаю с std::variant и std::visit, используя шаблон «перегрузки» , который выглядит так:

#include <iostream>
#include <variant>

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

int main(void) {
  std::variant<int, float> var;
  auto fs = overloaded {
    [](int var) {std::cout << "var is int" << std::endl;},
    [](float var) {std::cout << "var is float" << std::endl;}
  };
  var = 0;
  std::visit(fs, var);
  var = 0.0f;
  std::visit(fs, var);
}

На cppreference есть пример , в котором говорится:

// explicit deduction guide (not needed as of C++20)
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

Почему это руководство по выводам больше не требуется в C ++ 20? Удаление руководства по выводу типов приводит к сбою компиляции на всех текущих компиляторах , но никто полностью не поддерживает C ++ 20 прямо сейчас, так что это ничего не значит. Может ли кто-нибудь указать мне на ту часть SP c, в которой это обсуждается?

1 Ответ

4 голосов
/ 13 июля 2020

Это изменение было добавлено P1021R4 , в частности P1816R0 , в котором добавлена ​​поддержка вывода аргументов шаблона класса для агрегатов.

Специфическая формулировка c может быть находится в [over.match.class.deduct] / 1 , который добавляет, в основном, руководство по неявному выводу для агрегатов:

Кроме того, если C определено и его определение удовлетворяет условиям для агрегированного класса ([dcl.init.aggr]) с предположением, что любой зависимый базовый класс не имеет виртуальных функций и виртуальных базовых классов, а инициализатором является непустой braced-init -list или список выражений в скобках , и нет deduction-guides для C, набор содержит дополнительный шаблон функции, называемый совокупным кандидатом на дедукцию, определенным следующим образом. Пусть x1,…, xn будут элементами списка-инициализаторов или списка-назначенных-инициализаторов из список-инициализаторов в фигурных скобках или список-выражений . Для каждого xi пусть ei будет соответствующим агрегатным элементом C или одного из его (возможно, рекурсивных) подагрегатов, который будет инициализирован xi ([dcl.init.aggr]), если

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

Если нет такого агрегированного элемента ei для любого xi, агрегированный кандидат на вывод не добавляется в набор. Кандидат на совокупный вывод получается, как указано выше, из гипотетического конструктора C (T1,…, Tn), где

  • , если ei имеет тип массива, а xi - список инициализации в фигурных скобках или строка. -literal, Ti - это ссылка rvalue на объявленный тип ei, и
  • в противном случае Ti - это объявленный тип ei,

, за исключением того, что дополнительные пакеты параметров в форме Pj ... вставляются в список параметров в их исходной позиции агрегированного элемента, соответствующей каждому незавершенному агрегатному элементу типа Pj, который был пропущен, потому что это был пакет параметров, и завершающая последовательность параметров, соответствующая завершающему агрегатному элементу, который является расширение пакета (если оно есть) заменяется одним параметром формы Tn ....

В основном, руководство по вычету, которое вам приходилось писать раньше:

template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

теперь просто выпадает из языка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...