c++ - 结构化绑定(bind)顺序和评估

标签 c++ structured-bindings

很抱歉这个问题的标题不好,但我真的想不出更好的标题方式。我的问题涉及结构化绑定(bind)和映射,但在标准中找不到任何可以给我铸铁保证的东西。考虑以下几点:-

struct Obj {};

std::map<int, Obj> data;

if (const auto&[o, state] = data.insert(std::make_pair(0,  Obj())); state)
{
    // state is true if the object was inserted
}
else
{
    // Is it guaranteed that Obj() won't get called for a case where the key already exists?
    // Does the key get checked for its existence BEFORE the evaluation of the make_pair()?
}

在什么时候评估 key 的存在,或者这是从内到外评估所有内容的情况(因此创建了 Obj(),然后是 make_pair(),然后尝试了 .insert 等。

最佳答案

Does the key get checked for its existence BEFORE the evaluation of the make_pair()?

不,这不是 C++ 计算表达式的方式。 std::make_pair(0, Obj()) 已被完全评估,该对在传递给 insert 方法或与此相关的任何其他可调用之前构建。所以 Obj 在函数被调用之前总是存在的。

实现此功能需要某种形式的惰性求值。

但是对于这类问题有一个解决方案- try_emplace :

struct Obj {
   Obj(std::string, float, int);
};
int key=0;
data.try_emplace(key, "Str", 0.2f, 5)

这将首先检查键是否存在,如果存在,则不移动参数并返回 [iter,false]。否则,Obj("Str",0.2f,5) 将使用完美转发就地构建并返回 [iter,true]。后置条件是返回的迭代器总是指向一对等于参数的对。

这个解决方案的另一个好处是你不再需要为普通的 emplace 使用难看的 std::piecewise_construct 标签。

关于c++ - 结构化绑定(bind)顺序和评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65580683/

相关文章:

c++ - 在宏内的 if 语句中否定表达式会产生奇怪的结果

c++ - 按索引值按字母顺序对 vector 进行排序

C++11 正则表达式子串匹配

c++ - 结构体数据成员的Decltype,使用结构化绑定(bind)

c++ - 迭代元组 vector c+17 样式不起作用?

c++ - 为什么数组索引从 '0'开始

c++ - "free(): invalid pointer"在发布版本 (O3) 上调用 "libucis.so"时,我的代码从未到达

c++ - 为什么 GCC 会为结构化绑定(bind)诊断未使用的变量而 Clang 不会?

c++ - 来自 std::tuple 的引用绑定(bind)类型

c++ - 结构化绑定(bind)以获取子 vector 的连续元素而无需复制