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传给私有构造函数去初始化x和y。整个过程中读取函数只执行一次,而且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存在一个私有成员里,再用它来初始化x和y,同样能保证只读取一次文件,缺点是多占用了一点内存来存储这个临时的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




