返回时会复制 std::list<std::pair<string, string>> 这样的结构吗?
Will structure like std::list<std::pair<string, string>> be copied when returned?
我有一个函数可以从给定的字符串中提取键值列表,其中每个 key/value 对由 std::pair
表示,该函数具有如下签名:
std::list<std::pair<string, string>> extract(const string &s)
如果我的实现是这样的:
list<pair<...>> kv_pairs;
for (....) {
kv_pairs.push_back(make_pair(k, v));
}
return kv_pairs;
1) 我不希望发生任何复制,我想知道 RVO/NRVO 是否会应用于列表中的对以及包含它们的列表。
2) 如果在这种情况下会发生复制,那么在不复制的情况下实现它的替代数据结构可能是什么?我可以想到使用 unique_ptr<unorder_map<>>
的解决方案,但就我而言,我只需要支持列表中对的迭代,不需要支持通过键查找值,所以我想避免不必要的插入期间的哈希计算。
3) 我知道 RVO/NRVO 是依赖于编译器的行为,有没有什么方法可以验证这些行为是否容易发生?
- Will RVO happen when returning std::pair?
- What are copy elision and return value optimization?
如果您的编译目标至少为 C++11,那么实际上只有两种可能的结果:
- 在没有 RVO 的情况下,returned 临时对象将用于移动构造分配了 return 值的对象。这基本上只是洗牌一些指针,无论列表中有多少项,都将花费完全相同的时间(可以忽略不计)。
- 使用 RVO,省略了移动结构。
两种结果都非常快,不会涉及复制列表结构。
我有一个函数可以从给定的字符串中提取键值列表,其中每个 key/value 对由 std::pair
表示,该函数具有如下签名:
std::list<std::pair<string, string>> extract(const string &s)
如果我的实现是这样的:
list<pair<...>> kv_pairs;
for (....) {
kv_pairs.push_back(make_pair(k, v));
}
return kv_pairs;
1) 我不希望发生任何复制,我想知道 RVO/NRVO 是否会应用于列表中的对以及包含它们的列表。
2) 如果在这种情况下会发生复制,那么在不复制的情况下实现它的替代数据结构可能是什么?我可以想到使用 unique_ptr<unorder_map<>>
的解决方案,但就我而言,我只需要支持列表中对的迭代,不需要支持通过键查找值,所以我想避免不必要的插入期间的哈希计算。
3) 我知道 RVO/NRVO 是依赖于编译器的行为,有没有什么方法可以验证这些行为是否容易发生?
- Will RVO happen when returning std::pair?
- What are copy elision and return value optimization?
如果您的编译目标至少为 C++11,那么实际上只有两种可能的结果:
- 在没有 RVO 的情况下,returned 临时对象将用于移动构造分配了 return 值的对象。这基本上只是洗牌一些指针,无论列表中有多少项,都将花费完全相同的时间(可以忽略不计)。
- 使用 RVO,省略了移动结构。
两种结果都非常快,不会涉及复制列表结构。