结构化绑定顺序和评估
Structured Bindings Order and Evaluation
很抱歉这个问题的标题不好,但我真的想不出更好的标题方式。我的问题涉及结构化绑定和映射,但在标准中找不到任何可以给我 cast-iron 保证的内容。考虑以下几点:-
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()?
}
在什么时候评估密钥是否存在,或者这是从内到外评估所有内容的情况(因此创建了 Obj(),然后是 make_pair(),然后是 .插入尝试等
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)
是就地构造的,具有完美转发和 returns [iter,true]
。 post 条件是返回的迭代器总是指向等于参数的一对。
此解决方案的另一个好处是您不再需要为普通 emplace
.
使用难看的 std::piecewise_construct
标签
很抱歉这个问题的标题不好,但我真的想不出更好的标题方式。我的问题涉及结构化绑定和映射,但在标准中找不到任何可以给我 cast-iron 保证的内容。考虑以下几点:-
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()?
}
在什么时候评估密钥是否存在,或者这是从内到外评估所有内容的情况(因此创建了 Obj(),然后是 make_pair(),然后是 .插入尝试等
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)
是就地构造的,具有完美转发和 returns [iter,true]
。 post 条件是返回的迭代器总是指向等于参数的一对。
此解决方案的另一个好处是您不再需要为普通 emplace
.
std::piecewise_construct
标签