gpt4 book ai didi

c++ - std::forward_as__tuple 的用例

转载 作者:行者123 更新时间:2023-12-01 14:04:36 26 4
gpt4 key购买 nike

Cppreference 为 std::forward_as_tuple下面的例子(见 here)

#include <iostream>
#include <map>
#include <tuple>
#include <string>

int main()
{
std::map<int, std::string> m;

m.emplace(std::piecewise_construct,
std::forward_as_tuple(10),
std::forward_as_tuple(20, 'a'));
std::cout << "m[10] = " << m[10] << '\n';

// The following is an error: it produces a
// std::tuple<int&&, char&&> holding two dangling references.
//
// auto t = std::forward_as_tuple(20, 'a');
// m.emplace(std::piecewise_construct, std::forward_as_tuple(10), t);
}

简单写有什么好处
 m.emplace(std::make_pair(20,std::string(20,'a')));

最佳答案

它避免制作不必要的或可能不可能的对象拷贝。

首先,让我们考虑除 std::string 以外的值类型.我将使用无法复制的东西,但这也适用于可以复制但这样做很昂贵的东西:

struct NonCopyable
{
NonCopyable(int a, char b) {} // Dummy
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
};

我们如何将其插入 std::map<int, NonCopyable> m ?让我们来看看可能性:
m.insert({10, NonCopyable{10, 'a'}});

won't work .它接受对 std::pair 的引用并复制它,这需要复制 NonCopyable对象,这是不可能的。
m.emplace(10, NonCopyable{10, 'a'}});

这也 won't work .虽然它构造了 std::pair值到位,它仍然要复制 NonCopyable目的。
m.emplace(std::piecewise_construct,
std::tuple{10},
std::tuple{10, 'a'});

最后, works . std::pair element 是就地构造的,它的两个子对象也是如此。

但是让我们考虑另一种情况。考虑这个类:
struct UsesNonCopyable
{
UsesNonCopyable(const NonCopyable&) {}
UsesNonCopyable(const UsesNonCopyable&) = delete;
UsesNonCopyable& operator=(const UsesNonCopyable&) = delete;
};

现在我们如何向 std::map<int, UsesNonCopyable> m 添加元素?

由于与前一种情况相同的原因,上面的前两个选项不起作用,但突然之间第三个选项也不起作用:
m.emplace(std::piecewise_construct,
std::tuple{10},
std::tuple{NonCopyable{10, 'a'}});

won't work因为 NonCopyable对象必须复制到 std::tuple传递给 std::pair 的对象的构造函数。

这就是 std::forward_as_tuple进来:
m.emplace(std::piecewise_construct,
std::tuple{10},
std::forward_as_tuple(NonCopyable{10, 'a'}));

This works ,因为现在而不是通过 m.emplace包含 NonCopyable 拷贝的元组对象,我们使用 std::forward_as_tuple构造一个包含对 NonCopyable 的引用的元组目的。该引用被转发到 std::pair的构造函数,它将依次转发给 UsesNonCopyable的构造函数。

请注意,C++17 添加的 std::map::try_emplace 消除了大部分这种复杂性。只要您的 key 类型是可复制的。以下 will work很好,而且要简单得多:
std::map<int, UsesNonCopyable> m;
m.try_emplace(10, NonCopyable{10, 'a'});

关于c++ - std::forward_as__tuple 的用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61115338/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com