reference_wrapper:make_pair与VS类模板参数推导(CTAD)

时间:2018-11-26 14:20:47

标签: c++ templates c++17 template-deduction

为什么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 :(得分:6)

假设make_pair聪明

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

这称为overload unwrapping the 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);

另一方面,implicitly-generated deduction guides for std::pair保持原样。

答案 1 :(得分:3)

std::make_pair有一个特殊规则

  

推导的类型V1和V2是std::decay<T1>::typestd::decay<T2>::type(通常将类型转换应用于按值传递的函数的自变量)除非应用std::decay会导致{{ 1}}用于某些类型std::reference_wrapper<X>,在这种情况下,推导类型为X