繁体   English   中英

如何在 C++ 中迭代结构?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM