如何在C++20中模拟Kotlin数据类的copy()方法?
如何在C++20中模拟Kotlin数据类的copy()方法
问题1:C++20是否有原生支持该功能的语言特性?
没有。C20的聚合初始化虽支持指定成员(如{.a=10, .b="10"}),但无法直接基于已有对象仅修改部分成员——必须显式写出所有要保留的成员值,结构体成员较多时会繁琐且易出错。C23的部分特性(如std::forward_like结合结构化绑定改进)能更接近Kotlin的体验,但你无法使用C++23,因此需要自定义实现。
问题2:自定义copy()函数的实现建议
方案1:带默认参数的成员函数(简单直观)
给结构体添加copy成员函数,将每个参数的默认值设为当前对象的对应成员,调用时只需传入需要修改的成员:
#include <string> struct SomeData { int a; std::string b; SomeData copy(int new_a = a, std::string new_b = b) const { return {new_a, std::move(new_b)}; } }; // 使用示例 int main() { SomeData sd1 = {.a = 10, .b = "10"}; SomeData sd2 = sd1.copy(sd1.a, "ten"); // 仅修改b }
缺点:结构体成员增减或顺序改变时,需同步修改copy函数参数列表,维护成本较高。
方案2:基于lambda修改器的可变参数模板(灵活易维护)
实现接受任意数量lambda的copy函数,每个lambda负责修改新对象的指定成员,无需随结构体成员变化修改函数:
#include <string> #include <utility> struct SomeData { int a; std::string b; template<typename... Modifiers> SomeData copy(Modifiers&&... modifiers) const { SomeData new_obj = *this; // 先拷贝原对象 // 依次应用所有修改器 (std::forward<Modifiers>(modifiers)(new_obj), ...); return new_obj; } }; // 使用示例 int main() { SomeData sd1 = {.a = 10, .b = "10"}; // 仅修改b成员 SomeData sd2 = sd1.copy([](auto& obj) { obj.b = "ten"; }); // 同时修改a和b SomeData sd3 = sd1.copy( [](auto& obj) { obj.a = 20; }, [](auto& obj) { obj.b = "twenty"; } ); }
优点:结构体成员变化时无需修改copy函数,扩展性强;可同时修改任意数量的成员。
方案3:宏生成copy函数(减少重复代码)
若需给多个结构体添加copy功能,可用宏自动生成带默认参数的成员函数,避免重复编写:
#include <string> #define GENERATE_COPY_FUNC(StructName, ...) \ StructName copy(__VA_ARGS__) const { \ return {__VA_ARGS__}; \ } struct SomeData { int a; std::string b; GENERATE_COPY_FUNC(SomeData, int new_a = a, std::string new_b = b) }; // 使用示例同方案1
缺点:宏可读性较差,成员类型复杂(如带引用、const的成员)时需额外处理。
内容的提问来源于stack exchange,提问作者foo
相关产品推荐
相关产品推荐

