为什么make_pair <int,int>在C ++ 11中失败?

时间:2019-06-26 18:55:20

标签: c++ c++11 stl

下面的代码在以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的哪些变化使此代码不再兼容。

3 个答案:

答案 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_pairc++03c++11之间进行了更改。

您的代码失败,因为std::make_pair期望T&&U&&,其中TU是模板类型参数。 喜欢

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>

右值引用中添加了完美的转发; make_pair<int,int>具有签名(int&&, int&&)。这些都是右值引用,并且不能绑定到左值(例如u)。

make_pair<int, int&>(0, u)将编译并产生一个pair<int, int>,因为make_pair创建了一对值类型。

中没有右值引用,则不会发生此问题。可能make_pairmake_pair( A const&, B const& )而不是make_pair( A&&, B&& )