You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C++17中如何利用多返回值一次性初始化结构体多个const成员?

用C++17+一次性初始化结构体的const成员

好问题!你想要通过函数返回的std::pair一次性初始化结构体里的const成员,这个需求非常合理,但你原来的构造器写法是走不通的——C++的构造初始化列表不支持直接用结构化绑定的语法。下面给你两种靠谱的解决方案,其中第一种是最推荐的:

方案1:委托构造函数(最优解)

这种方法既能保证只调用一次read_from_file_all_values(),又能正确初始化const成员,还没有额外的内存开销:

#include <utility>
#include <iostream>

struct X {
private:
    // 私有构造函数:接收pair,直接用它的成员初始化x和y
    X(std::pair<int, double> values) : x(values.first), y(values.second) {}

public:
    // 默认构造函数委托给上面的私有构造函数,仅调用一次读取函数
    X() : X(read_from_file_all_values()) {}

    std::pair<int, double> read_from_file_all_values() {
        // 替换成你的实际文件读取逻辑
        std::cout << "读取文件一次..." << std::endl;
        return std::make_pair(1, 1.2);
    }

    const int x;
    const double y;
};

// 测试代码
int main() {
    X obj;
    std::cout << obj.x << " " << obj.y << std::endl;
    return 0;
}

为什么这能行?

默认构造函数通过委托构造的方式,先调用read_from_file_all_values()拿到完整的pair,再把这个pair传给私有构造函数去初始化xy。整个过程中读取函数只执行一次,而且const成员是在初始化列表里完成初始化的,完全符合C++的规则。

方案2:借助临时pair成员(备选)

如果你不介意结构体多一个私有成员变量,也可以用这种更直白的写法:

#include <utility>

struct X {
public:
    X() : stored_values(read_from_file_all_values()), 
          x(stored_values.first), 
          y(stored_values.second) {}

    std::pair<int, double> read_from_file_all_values() {
        return std::make_pair(1, 1.2);
    }

    const int x;
    const double y;

private:
    const std::pair<int, double> stored_values;
};

这里我们先把读取到的pair存在一个私有成员里,再用它来初始化xy,同样能保证只读取一次文件,缺点是多占用了一点内存来存储这个临时的pair

一定要避开的坑!

千万别直接在初始化列表里写:

// 错误!会调用两次read_from_file_all_values(),也就是读两次文件
X() : x(read_from_file_all_values().first), y(read_from_file_all_values().second) {}

这种写法会导致读取函数被执行两次,完全不符合你的预期,一定要避免。

内容的提问来源于stack exchange,提问作者Artur Pyszczuk

火山引擎 最新活动