在 C++ 中以 1 个表达式实例化对象的可自定义方式
Posted
技术标签:
【中文标题】在 C++ 中以 1 个表达式实例化对象的可自定义方式【英文标题】:Customizable way to instantiate objects in 1 expression in C++ 【发布时间】:2022-01-03 21:58:39 【问题描述】:在 Rust 中,有一个 crate,它利用 Rust 过程宏为定义的任意结构自动实现构建器模式。由于没有灵活的方法来使用一些默认值和一些提供的值来实例化 Rust 结构,这有助于减少样板文件。
有没有类似的东西可以在 C++ 中自动生成构建器,因为在 C++ 中实例化对象也需要大量样板文件(许多重载的构造函数来涵盖所有可能的字段组合或多步初始化),可能使用 C/C++宏?
正如 cmets 所建议的,我添加了一个示例来阐明我的想法。我想通过提供一些我想要的字段并将其他字段保留为默认值来实例化下面的 A 类。如果是这样,我要么必须实现很多构造函数,要么执行多个步骤,实例化然后覆盖我想要的字段:
多个构造函数#include <string>
#include <iostream>
class A
public:
int a = 2;
std::string b = "b";
int c = 5;
std::string d = "d";
A()
A(int a) this->a = a;
A(std::string b) this->b = b;
A(int a, std::string b)
this->a = a;
this->b = b;
// ... more constructors to cover all combinations
// this might not even work as some combinations might
// have similar types, which prevent overloading them
;
多个步骤
A a;
a.b = "hello";
a.c = 10;
多步骤实例化实际上很好。但是,如果我想在 1 个表达式中进行自定义实例化,则它不起作用。 使用构建器模式,我通过链接这样的方法在 1 个表达式中做到这一点:
BuilderOfA()
.a(7)
.c(8)
.build();
这个builder的定义可以在C++编译时自动生成吗?如果没有,我是否可以在不使用多个表达式的情况下以可自定义的方式实例化一个对象(只需提供一些我想要的字段并将其他字段保留为默认值)?
【问题讨论】:
“建造者模式”这个词本身就很模糊。 究竟你真的想要做什么?为什么你认为它会帮助你编写更好的代码? 核心 C++ 语言本身没有这样的东西。各种 C++ 开发工具可能会为创建一些样板提供一些自动化,但它会因工具和工具而异,或者软件建议对于 *** 来说不是合适的问题,抱歉。 @SamVarshavchik 我不认为 OP 是在要求工具或库推荐,他们只是在询问 stock C++ 是否可以在其中执行此操作 - 其中如果答案是“是的,但前提是您想推理数千行可变参数模板的乐趣!” 我个人不是我看到的(大多数)“构建器”类型和模式的超级粉丝(无论是哪种语言:C++、TypeScript、C#,或者最糟糕的:Java... )。好的老式构造函数有什么问题? XY-Problem - "...很多重载的构造函数来覆盖所有可能的字段组合..."然后编写强制执行它们的必要构造函数;你有一个设计问题,而不是代码或工具自动化问题。 【参考方案1】:在 c++ 20 中你可以这样做:
struct S
std::string str = "Hello";
float y = 1.0f;
int x = 10;
;
auto a = S .str = "Hi", .x = 8 ;
【讨论】:
我得到error: designator order for field ‘S::str’ does not match declaration order in ‘S’
试图编译这个。它的顺序应该正确:auto s = S.str = "Hi", .x = 8;
哎呀。您仍然需要匹配班级中的顺序。我添加了一个字符串以表明如果存在适当的构造函数,它将构造成员,并且在我这样做时忘记遵守顺序。
哦。我确认这段代码甚至可以在 c++14 上编译以上是关于在 C++ 中以 1 个表达式实例化对象的可自定义方式的主要内容,如果未能解决你的问题,请参考以下文章
使用在同一命名空间中定义的构造函数实例化命名空间中的对象。 C++