I am working on some core audio code and have a problem that could be solved by a variable array in a struct--a la Flexible Array Members. In doing a bit of looking around, I see that there is a lot of dialogue about the portability and viability of Flexible Member Arrays.
From what I understand, Objective-C is C99 compliant. For this reason, I think Flexible Array Members should be a fine solution. I also see that Flexible Array Members are not a good idea in C++.
What to do in Objective-C++? Technically,开发者_如何学C I won't use it in Objective-C++. I am writing callbacks that are C and C++ based... That seems like a point against.
Anyway, can I (should I) do it? If not, is there another technique with the same results?
You can always just declare a trailing array of size 1. In the worst case here, you waste a pretty small amount of memory, and it is very slightly more complicated to compute the right size for malloc.
don't bother. it's not compatible. it is messy and error prone. c++ had solutions which are managed more easily long before this feature existed. what are you tacking onto the end of your struct? normally, you'll just use something like a std::vector, std::array, or fixed size array.
UPDATE
I want to have a list of note start times (uint64_t) and iterate through them to see which, if any, is playing. i was going to add a count var to the struct to track how many items are in the flexible array.
ok, then a fixed size array should be fine if you have fixed polyphony. you will not need more than one such array in most iOS synths. of course, 'upcoming note' array sizes could vary based on the app synth? sampler? sequencer? live input?
template <size_t NumNotes_>
class t_note_start_times {
public:
static const size_t NumNotes = NumNotes_;
typedef uint64_t t_timestamp;
/*...*/
const t_timestamp& timestampAt(const size_t& idx) const {
assert(this->d_numFutureNotes <= NumNotes);
assert(idx < NumNotes);
assert(idx < this->d_numFutureNotes);
return this->d_startTimes[idx];
}
private:
t_timestamp d_presentTime;
size_t d_numFutureNotes; // presumably, this will be the number of active notes,
// and values will be compacted to [0...d_numFutureNotes)
t_timestamp d_startTimes[NumNotes];
};
// in use
const size_t Polyphony = 16;
t_note_start_times<Polyphony> startTimes;
startTimes.addNoteAtTime(noteTimestamp); // defined in the '...' ;)
startTimes.timestampAt(0);
if you need a dynamically sized array which could be very large, then use a vector. if you need only one instance of this and the max polyphony is (say) 64, then just use this.
精彩评论