c++ - 如何将几个布尔标志包装到结构中,以使用方便的语法将它们传递给函数
问题描述
在一些测试代码中有一个这样的辅助函数:
auto make_condiment(bool salt, bool pepper, bool oil, bool garlic) {
// assumes that first bool is salt, second is pepper,
// and so on...
//
// Make up something according to flags
return something;
};
它基本上是something
基于一些bool
ean 标志建立的。
我担心的是每个参数的含义bool
都是硬编码在参数名称中的,这很糟糕,因为在调用站点很难记住哪个参数意味着什么(是的,IDE 可以通过显示这些名称来完全消除问题制表符完成,但仍然...):
// at the call site:
auto obj = make_condiment(false, false, true, true); // what ingredients am I using and what not?
因此,我想传递一个描述设置的对象。此外,只需将它们聚合到一个对象中,例如std::array<bool,4>
.
相反,我想启用这样的语法:
auto obj = make_smart_condiment(oil + garlic);
这将生成与obj
先前调用相同的make_condiment
.
这个新功能将是:
auto make_smart_condiment(Ingredients ingredients) {
// retrieve the individual flags from the input
bool salt = ingredients.hasSalt();
bool pepper = ingredients.hasPepper();
bool oil = ingredients.hasOil();
bool garlic = ingredients.hasGarlic();
// same body as make_condiment, or simply:
return make_condiment(salt, pepper, oil, garlic);
}
struct Ingredients {
public:
enum class INGREDIENTS { Salt = 1, Pepper = 2, Oil = 4, Garlic = 8 };
explicit Ingredients() : flags{0} {};
explicit Ingredients(INGREDIENTS const& f) : flags{static_cast<int>(f)} {};
private:
explicit Ingredients(int fs) : flags{fs} {}
int flags; // values 0-15
public:
bool hasSalt() const {
return flags % 2;
}
bool hasPepper() const {
return (flags / 2) % 2;
}
bool hasOil() const {
return (flags / 4) % 2;
}
bool hasGarlic() const {
return (flags / 8) % 2;
}
Ingredients operator+(Ingredients const& f) {
return Ingredients(flags + f.flags);
}
}
salt{Ingredients::INGREDIENTS::Salt},
pepper{Ingredients::INGREDIENTS::Pepper},
oil{Ingredients::INGREDIENTS::Oil},
garlic{Ingredients::INGREDIENTS::Garlic};
但是,我有一种重新发明轮子的感觉。
有没有更好或标准的方法来完成上述工作?
是否有我可以/应该使用的设计模式?
解决方案
如果您想使用枚举作为标志,通常的方法是将它们合并operator |
并检查它们operator &
#include <iostream>
enum Ingredients{ Salt = 1, Pepper = 2, Oil = 4, Garlic = 8 };
// If you want to use operator +
Ingredients operator + (Ingredients a,Ingredients b) {
return Ingredients(a | b);
}
int main()
{
using std::cout;
cout << bool( Salt & Ingredients::Salt ); // has salt
cout << bool( Salt & Ingredients::Pepper ); // doesn't has pepper
auto sp = Ingredients::Salt + Ingredients::Pepper;
cout << bool( sp & Ingredients::Salt ); // has salt
cout << bool( sp & Ingredients::Garlic ); // doesn't has garlic
}
注意:如果你混合喜欢,当前代码(只有operator +
)将不起作用。|
+
(Salt|Salt)+Salt
也可以使用enum class
,只需要定义操作符
推荐阅读
- php - 如何从 php 更改“base” HEAD 标签?
- java - 如何从 Elastic Beanstalk 中的 Spring Boot 应用程序中获取客户端主机名和/或客户端 IP 地址?
- c# - TempData 删除数据
- typescript - 在量角器中自动化 E2E,删除一个事件后如何获取事件计数
- macos - 为什么 Fastscripts 可以使用此功能,但鸭嘴兽却不能
- python - 如何在matplotlib python中删除以前的散点图
- javascript - html 中的工具提示
- iis - 更改 sitecore 网站默认 URL 结构
- outlook - WebDAV 上发布的 Outlook 日历未在 Google 日历上更新?
- python - python的查找功能出现问题