还包括现有变量的 C++17 结构化绑定(bind)

标签 c++ refactoring c++17 structured-bindings

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/

相关文章:

c++ - 将对象 int 数据成员转换为 float 并除法将奇怪的数据 cout 附加到控制台

c# - 如何最好地重构嵌套 switch 语句?

c++ - 提供显式演绎指南是否会禁用隐式演绎指南的生成/形成

c++ - C++17 之前是否存在 if 语句中的初始化?

c++ - 为什么 "return *this"返回一个引用?

c++临时对象创建了吗?

c++ - 从 shared_ptr 中提取原始指针

java - 我怎样才能减少这个的圈复杂度?

无需重构的 Android Studio 重命名

c++ - 为什么在 C++11 或 C++14 中,当我声明移动赋值运算符时,编译器会隐式删除复制构造函数?