Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Use of std::find_if with flexible arrays

Let’s say that I have the following two structures, where struct sB has a flexible array:

struct sA
{
  double valueA;
  double valueB;
};

struct sB
{
  double c;
  size_t arrayMembers;
  sA aM[];
};

I want to iterate over aM and find the first element with valueA > c and valueB > c. I want to do it using std::find_if().

I tried to use std::begin() and std::end():

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

auto primeElement = std::find_if(std::begin(sBInstance.aM), std::end(sBInstance.aM),
      [&](const sB v){return (v.valueA > c && v.valueB > c)});

However, it doesn’t compile with a compiler error (among other related errors):

‘std::begin’ : no matching overloaded function found

I think that flexible arrays are more C than C++, and C++ iterators maybe are not particularly suited to them, but is there a way I can use std::find_if() on a flexible array? If there is more than one way, which one is the most straightforward?

>Solution :

Standard C++ does not support flexible array members. Those are a C feature that are not part of C++. If you need an object with a variable-length array as a member, use std::vector instead.


If you compiler supports flexible array members as an extension, you’ll need to treat them more like pointers to dynamically-allocated arrays than statically-sized C arrays. Since their size is not known at compile time, std::end cannot statically compute an appropriate offset. Instead, you’ll need to add an offset of arrayMembers to a pointer to the first element of the array:

auto primeElement = std::find_if(
    sBInstance->aM,
    sBInstance->aM + sBInstance->arrayMembers,
    [&](const sA& v){return v.valueA > c && v.valueB > c}
);

This works because pointers are a type of iterator, so pointers to the beginning and one past the end of an array are a valid iterator range to iterate over that array.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading