[英]how to iterate struct in C++?
我在 struct Flags
中有很多 bool 变量:
struct Flags
{
bool isATrue;
bool isBTrue;
bool isCTrue;
...
}
然后在另一个 function 中,我计算了这些变量的 bool 结果值,现在我必须将 true 的变量放入新的 Vector.eg if isBtrue == true
中。 我必须将isBtrue
放在 Vector TrueFlags
中。 但是 C++ 不支持 for() 循环来迭代结构。 有人有什么好主意吗?如何在 C++ 中迭代结构?
您可以使用std::bitset
并具有:
// 3 stands for 3 flags you have in your struct
std::bitset<3> flags;
flags.set(0); // set bit at position 0 to true
flags.set(2); // set bit at position 2 to true
然后你可以遍历它:
for (std::size_t i{ 0 }; i < flags.size(); ++i) {
// access with flags[i]
}
您还可以为直接标志访问创建枚举,例如:
enum Flags {
IsATrue = 0,
IsBTrue,
IsCTrue
};
然后像这样使用它: flags[IsATrue]
。
如果值的数量是固定的并且事先已知,则可以使用array<bool>
,否则使用vector<bool>
。 同样对于 is_true 变量。 然后你可以很容易地循环它。
一种方法是使用其他答案中所述的 bitset。 但是,如果结构Flags
是您必须使用的东西(无论出于何种原因,例如可能存在 API 等),您可以使用操作包装器和指向成员的指针来实现“循环能力”。 类似的东西(见Live ):
struct Flags
{
bool isATrue;
bool isBTrue;
bool isCTrue;
};
struct FlagsOp
{
FlagsOp(Flags& f)
: f{ f }
, v({ &Flags::isATrue, &Flags::isBTrue, &Flags::isCTrue })
{}
size_t size() const { return v.size();}
bool& operator[](size_t n) { return f.*(v[n]); }
private:
Flags& f;
vector<bool Flags::*> v;
};
int main()
{
Flags f{};
FlagsOp fop(f);
fop[0] = true; // isATrue
fop[1] = true; // isBTrue
fop[2] = true; // isCTrue
for (size_t i = 0; i < fop.size(); ++i)
cout << fop[i] << '\n';
}
如果您不想更改struct Flags
,还有另一种方法。 但首先请阅读本文并注意这不是一个可移植的解决方案。 您可以通过定义这样的联合来利用联合:
union Flagsunion{
bool flag[sizeof(Flags)/ sizeof(bool)];
Flags flags;
};
假设您的std::vector<bool>
的名称是myvector
并且您的Flags
的名称是myflags
然后在您的代码中:
std::vector<bool> myvector;
Flags myflags{ true, false, true};
Flags2 my2ndflags;
my2ndflags.flags = myflags;
for(int i = 0; i < 3; ++ i){
myvector.push_back(my2ndflags.flag[i]);
}
如何在 C++ 中迭代结构?
与迭代任何没有预先存在的标准迭代器的方法相同:通过编写自定义迭代器。
编写自定义迭代器并不简单,而且由于缺乏自省的语言特性,编写这个自定义迭代器特别复杂,,。 一个不完整的简化示例:
struct Flags
{
bool isATrue;
bool isBTrue;
bool isCTrue;
struct iterator {
Flags* flags;
int index;
bool& operator*() {
switch(index) {
case 0: return flags->isATrue;
case 1: return flags->isBTrue;
case 2: return flags->isCTrue;
default: throw std::out_of_range("You wrote a bug!");
}
}
iterator& operator++() {
index++;
return *this;
}
iterator operator++(int) {
iterator next = *this;
index++;
return next;
}
friend auto operator<=>(const iterator&, const iterator&) = default;
};
iterator begin() {
return {this, 0};
}
iterator end() {
return {this, 3};
}
};
请注意,虽然可以在 C++ 中迭代 class 的成员,但这不一定有效。 如果您需要高效的迭代,建议使用数组而不是 class。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.