下面的代码在以C ++ 98编译时可以正常工作,但在C ++ 11上失败。
#include <iostream>
#include <utility>
using namespace std;
int main()
{
int u = 1;
pair<int, int> p = make_pair<int, int>(0, u);
cout << p.first << " " << p.second << "\n";
}
来自g ++(Debian 8.3.0-6)8.3.0的错误消息是:
foo.cpp: In function ‘int main()’:
foo.cpp:9:45: error: no matching function for call to ‘make_pair<int, int>(int, int&)’
pair<int, int> p = make_pair<int, int>(0, u);
^
我知道我可以通过从make_pair
中删除模板说明符并让编译器自行决定类型来简单地进行编译。但是我有兴趣了解从C ++ 98到C ++ 11的哪些变化使此代码不再兼容。
答案 0 :(得分:7)
在c ++ 11之前,有
template< class T1, class T2 >
std::pair<T1,T2> make_pair( T1 t, T2 u );
您将T1和T2定义为int
,因此int
可以采用Lvalues和Rvalues。
自c ++ 11起,您拥有
template< class T1, class T2 >
std::pair<V1,V2> make_pair( T1&& t, T2&& u );
因为T2
被定义为int
,所以int&&
作为第二个参数只能采用Rvalues。但是u
是左值。
答案 1 :(得分:4)
std::make_pair在c++03
和c++11
之间进行了更改。
您的代码失败,因为std::make_pair
期望T&&
和U&&
,其中T
和U
是模板类型参数。
喜欢
template <typename T, typename U>
std::pair<V1,V2> make_pair(T&& argT, U&& argU);
还是要同时指定这两个参数,请使用pair<int, int>
示例-
#include <iostream>
#include <utility>
using namespace std;
int main() {
int u = 1;
pair<int, int> p = pair<int, int>(0, u);
cout << p.first << " " << p.second << "\n";
}
您可以在此处了解更多详细信息-utility-make_pair
答案 2 :(得分:2)
您不应将类型参数传递给make_pair
;它旨在推论其论点。如果您想制作某种完全可以创建某种类型的东西,只需执行std::pair<int, int>
。
在c++11右值引用中添加了完美的转发; make_pair<int,int>
具有签名(int&&, int&&)
。这些都是右值引用,并且不能绑定到左值(例如u
)。
make_pair<int, int&>(0, u)
将编译并产生一个pair<int, int>
,因为make_pair
创建了一对值类型。
在c++03中没有右值引用,则不会发生此问题。可能make_pair
是make_pair( A const&, B const& )
而不是make_pair( A&&, B&& )
。