I have two versions of a function. One returns by value, intended for use as an r-value. The other returns by reference, intended for use as an l-value (to write to the audio_data vector).
float AudioData::sample(unsigned frame, unsigned channel) const
{
return audio_data[frame * channel_count + channel];
}
float& AudioData::sample(unsigned frame, unsigned channel)
{
clearSplits(); // Clear out cached information that may be invalidated by this call
return audio_data[frame * channel_count + channel];
}
While debugging, I've noticed that the reference-returning override is getting used as an r-value:
const float *AudioData::split(unsigned channel)
{
if (splits[channel] != nullptr) return splits[channel];
if (channel_count == 1) return data();
float *split = new float[frame_count];
for (unsigned i = 0; i < frame_count; ++i)
{
split[i] = sample(i, channel); // Calls the reference-returning override
}
splits[channel] = split;
return split;
}
void AudioData::clearSplits() // This gets called while writing to the splits!
{
for (unsigned i = 0; i < splits.size(); ++i)
{
if (splits[i] != nullptr) delete[] splits[i];
splits[i] = nullptr;
}
}
Why does the compiler opt to use the non-const l-value override when it's not modifying the return reference and how can I prevent it from doing so?