如何在类构造函数的初始化列表中使用std::tie调用foo函数初始化成员变量x、y、z
如何在类构造函数的初始化列表中使用std::tie调用foo函数初始化成员变量x、y、z
当然能做到!完全符合你的要求——只调用一次昂贵的foo,还能在构造函数的初始化列表里搞定x、y、z的初始化。这里给你两种实用方案,适配不同的C++版本:
方案一:委托构造函数(兼容C++11及以上)
这是最通用的路子,不管你用的是C++11还是更新的版本都能用。思路很简单:先搞一个私有构造函数,专门接收foo返回的tuple,用它直接初始化x、y、z;然后公共的构造函数调用foo之后,把返回的tuple传给这个私有构造函数,这样foo只会被调用一次,完美避免重复调用的性能浪费。
代码示例:
#include <string_view> #include <tuple> std::tuple<int, int, int> foo(std::string_view sv); class s { public: s(std::string_view sv); private: // 私有构造函数,接收tuple并初始化成员 explicit s(std::tuple<int, int, int> t) : x(std::get<0>(t)), y(std::get<1>(t)), z(std::get<2>(t)) {} int x, y, z; }; // 公共构造函数,调用foo后委托给私有构造 s::s(std::string_view sv) : s(foo(sv)) {}
这个方案的优势很明显:
- 严格在初始化列表里完成x、y、z的初始化,不是后续的赋值操作
- 只调用一次
foo,完全符合你对性能的要求 - 兼容所有支持C++11及以上的编译器
方案二:C++17及以上的简化写法(结合结构化绑定)
如果你已经用上C++17或者更新的版本,还可以用结构化绑定让代码看起来更清爽。不过要注意,这种写法是在构造函数体里做赋值,不是严格的初始化列表,但foo还是只调用一次,也能满足你的核心要求。
代码示例:
#include <string_view> #include <tuple> std::tuple<int, int, int> foo(std::string_view sv); class s { public: s(std::string_view sv) { auto [a, b, c] = foo(sv); x = a; y = b; z = c; } private: int x, y, z; };
为啥不能直接用std::tie在初始化列表里?
你可能会好奇,为啥不能直接在初始化列表里写std::tie(x, y, z) = foo(sv);?因为初始化列表的作用是初始化成员变量,不是用来执行赋值语句的。std::tie的赋值是一个操作语句,没法放在初始化列表的成员初始化位置,所以上面两种方案才是合规的正确做法。
备注:内容来源于stack exchange,提问作者Dominik Kaszewski
相关产品推荐
相关产品推荐

