在C++ STL中,std::pair中使用`std::make_pair`的用途是什么?

5
我注意到很多时候,当我们需要给一个(新的)std::pair赋值时,会使用std::make_pair函数。但我发现并没有必要使用make_pair函数,因为我们可以直接输入值到一个pair中,并按照自己的需求进行修改。 例如:
std::pair<int,int> newp;
std::cin>>newp.first>>newp.second;
newp.first = -1;

那么这个函数到底有什么用处呢?

1
现在尝试使用没有默认构造函数的类型来完成这个任务。 - milleniumbug
@milleniumbug:观察得很好,但是std::make_pair也有同样的问题。从根本上讲,这是语言和库之间的设计问题。你不能简单地编写一个由输入流按顺序初始化的异构对象声明列表。最接近的方法是定义带有流参数的构造函数,并为内置类型在流上进行转换操作。但是,使用这种风格仍然需要大量重复流名称。 - MSalters
可能是std :: make_pair与std :: pair构造函数的目的是什么?的重复问题。 - Jan Deinhard
3个回答

6

std::make_pair 用于创建一个具有指定值的 std::pair 对象。

通过推导参数类型来创建 std::pair 对象。

作为一个支持自动模板参数类型推导的模板函数,它允许您省略指定目标模板参数类型。例如,

auto p1 = std::make_pair(1, 2);  // p1 is std::pair<int, int> with value {1, 2}

5

这里有一个优点,它被称为模板参数推导。它节省了一些打字,并且允许您使用auto类模板的参数必须明确指定,而函数则不必。


但是随着 C++17 的出现,这变得多余了,因为我们将拥有 类模板的模板参数推导


3

we can directly input values to a pair, and modify them as we like. For example:

std::pair<int,int> newp;
std::cin>>newp.first>>newp.second;
newp.first = -1;
我可以想到一些问题:
  1. 你并不总是有一个流对象准备就绪。std::cin 是一个非常特殊的情况,而 std::make_pair 是一个非常通用的函数。

  2. 谁说这个 pair 中的两种类型都支持 operator>> 运算符呢?

  3. 常量正确性。你可能想要一个 const 的 pair。

让我们把这三件事结合起来,创建一个不能编译的示例:
#include <utility>
#include <iostream>

struct Foo
{
    int i;
};

struct Bar
{
    double d;
};

void printPair(std::pair<Foo, Bar> const& pair)
{
    std::cout << pair.first.i << " " << pair.second.d << "\n";
}

void createAndPrintPairTwice(Foo const& foo, Bar const& bar)
{
    // error 1: no std::cin, need to use foo and bar
    // error 2: no operator>> for Foo or Bar
    // error 3: cannot change pair values after initialisation
    std::pair<Foo, Bar> const newp;
    std::cin >> newp.first >> newp.second;
    printPair(newp);
    printPair(newp);
}

int main()
{
    Foo foo;
    foo.i = 1;
    Bar bar;
    bar.d = 1.5;
    createAndPrintPairTwice(foo, bar);
}

std::make_pair 可以解决这三个问题,并使代码更易读。请注意,您不必重复对pair的模板参数:

void createAndPrintPairTwice(Foo const& foo, Bar const& bar)
{
    std::pair<Foo, Bar> const pair = std::make_pair(foo, bar);
    printPair(pair);
    printPair(pair);
}

事实是,C++11使得std::make_pair比以前不再那么有用,因为现在你可以写出以下代码来:
void createAndPrintPairTwice(Foo const& foo, Bar const& bar)
{
    auto const pair = std::pair<Foo, Bar> { foo, bar };
    printPair(pair);
    printPair(pair);
}

是的,我现在明白了。它现在只在某些地方有用! - Sahil Arora

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接