This SO answer列出了 C++17 分解声明(以前称为“结构化绑定(bind)”的功能)的一些缺点。例如,您不能为新变量指定显式类型,等等。但是那里没有提到我遇到的一个大缺点,所以我想知道是否有一个我只是没有想到的已知解决方法。
考虑 this JSON-parsing code (可能包含其他错误;出于此问题的目的请忽略它们):
using Value = std::any;
using String = std::string;
using Object = std::map<String, Value>;
std::pair<String, const char *> load_string(const char *p, const char *end);
std::pair<Value, const char *> load_value(const char *p, const char *end);
const char *skip_spaces(const char *p, const char *end);
std::pair<Object, const char *> load_object(const char *p, const char *end)
{
p = skip_spaces(p, end);
if (p == end || *p++ != '{') throw ParseError("Expected {");
p = skip_spaces(p, end);
Object result;
if (p == end && *p == '}') {
// the object has no key-value pairs at all
} else {
while (true) {
auto [key, p] = load_string(p, end);
p = skip_spaces(p, end);
if (p == end || *p++ != ':') throw ParseError("Expected :");
auto [value, p] = load_value(p, end);
result.insert_or_assign(std::move(key), std::move(value));
p = skip_spaces(p, end);
if (p == end) throw ParseError("Expected , or }");
if (*p == '}') break;
if (*p++ != ',') throw ParseError("Expected , or }");
}
}
return {result, p+1};
}
这会很好用,除了以 auto [key, p] =
和 auto [value, p] =
开头的行是无效的!变量 p
已经声明。我正在尝试为 p
分配一个新的值,但我不想创建一个全新的局部变量。
我不希望使用 std::tie(key, p) =
,因为这需要我在赋值之前为 key
声明。这是对 std::tie
的熟悉的旧异议。我可以发誓,这就是将结构化绑定(bind)引入该语言的原因!
那么是否有任何解决方法——编写组合构造的任何干净的方法-key
-in-place-and-also-assign-to-p
表示我的意图?
奇怪的是我以前从来没有错过过这个功能,但是一旦你给我结构化绑定(bind)来玩,我尝试的第一件事就不管用了。 :(
最佳答案
在具有更复杂类型的情况下,可移动临时新对象的简单解决方法可能是朝着您想要的方向迈出的最简单的理想步骤(尽管我认为在您的特定情况下,坚持使用传统的 tie
可能更简单):
... // (as in your code: p & end exist already, key & p_ not yet)
auto [key, p_] = load_string(p, end);
p = move(p_);
... // (continue using p)
很抱歉,我最终无法自己编译它,尽管我认为这是我的 IDE 的问题(CLion 目前仅半支持 C++17),但我希望它能正常工作。
关于还包括现有变量的 C++17 结构化绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42590449/