-2

Any idea how to rewrite this lambda function pre c++11?

    if (maxVol != 0)
       std::transform(&spec[0], &spec[sampleSize], &spec[0]
                     , [maxVol] (float dB) -> float {   return dB / maxVol; });

The code is from http://katyscode.wordpress.com/2013/01/16/cutting-your-teeth-on-fmod-part-4-frequency-analysis-graphic-equalizer-beat-detection-and-bpm-estimation

Thanks

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
JasperK
  • 71
  • 1
  • 6

2 Answers2

5

Origional code:

if (maxVol != 0)
       std::transform(&spec[0], &spec[sampleSize], &spec[0], [maxVol] (float dB) -> float {   return dB / maxVol; });

Lambda:

[maxVol] (float dB) -> float {   return dB / maxVol; }

Replacement for lambda:

struct percent_of {
    //that lambda captures maxVol by copy when constructed
    percent_of(float maxVol) : maxVol(maxVol) {} 
    //the lambda takes a "float dB" and returns a float
    float operator()(float dB) const { return dB / maxVol; }
private:
    float maxVol;
};

Replacement for full code:

if (maxVol != 0)
       std::transform(&spec[0], &spec[sampleSize], &spec[0], percent_of(maxVol));

However, this lambda is so simple, that it is now built into the standard library. Pre-C++11 had these exact same bits in boost.

if (maxVol != 0) {
    using std::placeholders::_1;
    auto percent_of = std::bind(std::divides<float>(), _1, maxVol);
    std::transform(&spec[0], &spec[sampleSize], &spec[0], percent_of);
}
Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
  • I get the errors: 'FrequencyAnalysis::DrawScene()::percent_of' does not have any field named 'maxVol' and use of 'auto' variable from containing function. It doesn't recognize the function inside the std::transform either. Any help would be greatly appreciated, thanks. – JasperK Apr 07 '14 at 12:05
  • The first was caused by a typo in the name of `maxVol`, and the second by forgetting to actually instantiate `divides`. I've corrected those. The third error merely stems from the first two, but the code works now, instead of merely being a guideline. http://coliru.stacked-crooked.com/a/8d8b42fa15ad94ba – Mooing Duck Apr 07 '14 at 15:21
  • sorry i still get the error: 'no matching function for call to 'transform(float*, float *, float *, FrequencyAnalysis::DrawScene()::percent_of)' – JasperK Apr 08 '14 at 01:53
  • did you `#include `? – Mooing Duck Apr 08 '14 at 02:15
  • yes i did, i'm a bit stumped. I cant use your second method as that throws up errors due to the version of c++ i'm writing in. – JasperK Apr 08 '14 at 12:31
  • Can you open the output window and give us the full error text? I can't imagine what the problem could be – Mooing Duck Apr 08 '14 at 16:06
  • I have sorted it now, just needed to define the struct within my header file! Thankyou – JasperK Apr 09 '14 at 14:05
0
  1. Use bind1st and bind2nd (in C++11 we would just use bind) for a predicate which also takes maxVol as one of its inputs

  2. Create a function object which can have a member variable for maxVol. Overload operator() and pass this in as a predicate.

  3. Use boost lambda.
MS Srikkanth
  • 3,829
  • 3
  • 19
  • 33