reference_wrapper: make_pair VS Вывод аргумента шаблона класса (CTAD) - PullRequest
0 голосов
/ 26 ноября 2018

Почему make_pair и метод вычета аргументов шаблона класса (CTAD) не согласовывают, какой тип генерировать?

#include <iostream>
#include <functional>
#include <utility>
#include <typeinfo>

int main() {
    int myInt = 5;
    std::reference_wrapper<int> myIntRef = myInt;
    auto myPair = std::make_pair(myInt, myIntRef);
    std::pair My2ndPair(myInt, myIntRef);
    std::cout << typeid(myPair).name() << '\n';
    std::cout << typeid(My2ndPair).name() << '\n';
}

Вывод:

St4pairIiRiE                       // std::pair<int, int&>
St4pairIiSt17reference_wrapperIiEE // std::pair<int, std::reference_wrapper<int> >

Обновление:

Почему направляющие вычетов для std::pair не содержат направляющих для std::reference_wrapper, например, make_pair имеет перегрузку?

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Существует специальное правило для std :: make_pair

Выведенные типы V1 и V2: std::decay<T1>::type и std::decay<T2>::type (обычные преобразования типов, применяемые к аргументамфункции, передаваемые по значению) , если применение std::decay не приведет к std::reference_wrapper<X> для некоторого типа X, и в этом случае выведенный тип будет X&.

0 голосов
/ 26 ноября 2018

Поскольку make_pair является умным :

std::reference_wrapper<int> myIntRef = myInt;
auto myPair = std::make_pair(myInt, myIntRef);

Это вызывает перегрузку , развертывающую std::reference_wrapper<int>:

template<class T1, class T2>
  constexpr pair<unwrap_ref_decay_t<T1>, unwrap_ref_decay_t<T2>> make_pair(T1&& x, T2&& y);

С другой стороны, неявно сгенерированные инструкции по выводу для std::pair принимают типы как есть.

...