为什么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
的指南?
答案 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>::type
和std::decay<T2>::type
(通常将类型转换应用于按值传递的函数的自变量)除非应用std::decay
会导致{{ 1}}用于某些类型std::reference_wrapper<X>
,在这种情况下,推导类型为X
。