无法从 C++17 之前的构造函数中推断出类模板参数
在 C++17 之前,你不能写类似的东西:
std::pair p(1, 'a');
因为这会从构造函数参数中推断出模板类型,所以您必须将其显式编写为:
std::pair<int,char> p(1, 'a');
C++17 使这种语法成为可能,因此 make_pair 是多余的。
在 C++17 之前,std::make_pair 允许我们编写更少冗长的代码:
MyLongClassName1 o1;
MyLongClassName2 o2;
auto p = std::make_pair(o1, o2);
而不是更冗长的:
std::pair<MyLongClassName1,MyLongClassName2> p{o1, o2};
重复类型,可以很长。
类型推断适用于 C++17 之前的情况,因为 make_pair 不是构造函数。
make_pair 本质上等同于:
template<class T1, class T2>
std::pair<T1, T2> my_make_pair(T1 t1, T2 t2) {
return std::pair<T1, T2>(t1, t2);
}
同样的概念适用于inserter 和insert_iterator。
另见:
小例子
为了使事情更具体,我们可以通过以下方式最小化观察问题:
main.cpp
template <class MyType>
struct MyClass {
MyType i;
MyClass(MyType i) : i(i) {}
};
template<class MyType>
MyClass<MyType> make_my_class(MyType i) {
return MyClass<MyType>(i);
}
int main() {
MyClass<int> my_class(1);
}
然后:
g++-8 -Wall -Wextra -Wpedantic -std=c++17 main.cpp
编译愉快,但是:
g++-8 -Wall -Wextra -Wpedantic -std=c++14 main.cpp
失败:
main.cpp: In function ‘int main()’:
main.cpp:13:13: error: missing template arguments before ‘my_class’
MyClass my_class(1);
^~~~~~~~
并且需要改为工作:
MyClass<int> my_class(1);
或助手:
auto my_class = make_my_class(1);
它使用常规函数而不是构造函数。
std::reference_wrapper 的区别
This comment 提到 std::make_pair 解包 std::reference_wrapper 而构造函数没有,所以这是一个区别。 TODO 示例。
用GCC 8.1.0, Ubuntu 16.04测试。