Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost transform iterator and c++11 lambda

I'm trying to use boost::adaptors::transformed by providing a c++0x lambda to the adaptor.

The following code does not compile. I'm using g++ 4.6.2 with boost 1.48.

#include <iostream>
#include <vector>

#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>

using namespace std;
namespace br    = boost::range;
namespace badpt = boost::adaptors;


int main()
{  
  vector<int> a = {0,3,1,};
  vector<int> b = {100,200,300,400};

  auto my_ftor = [&b](int r)->int{return b[r];};

  cout<<*br::max_element(a|badpt::transformed(my_ftor))<<endl;
}

Any ideas on what I'm doing wrong here?

like image 222
Nithin Avatar asked Oct 01 '12 11:10

Nithin


2 Answers

@ForEver's answer (#define BOOST_RESULT_OF_USE_DECLTYPE) didn't work for me. And @Paul's answer is too long (and too general). A more specific solution can be this:

#include <iostream>
#include <vector>

#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>

using namespace std;
namespace br    = boost::range;
namespace badpt = boost::adaptors;


int main()
{  
  vector<int> a = {0,3,1,};
  vector<int> b = {100,200,300,400};

  struct{
     vector<int>* bP;                               //pointer, just to imitate lambda syntax...
     int operator()(int r) const{return (*bP)[r];}  //was my_ftor = [&b](int r)->int{return b[r];};
  } my_ftor{&b};                                    //...here

  cout<<*br::max_element(a|badpt::transformed(my_ftor))<<endl;
}

(It is 2016, Boost 1.58 and this is still broken. At least lambda without captures should fulfill the requirements of boost::transformed.)

If the lambda didn't have a capture (not your case) the code would be a bit simpler OR you could use:

...
int(*my_ftor)(int) = [](int r)->int{return ...;}; // function pointer default constructible and callable
cout<<*br::max_element(a|badpt::transformed(my_ftor))<<endl;
...
like image 98
alfC Avatar answered Sep 25 '22 03:09

alfC


It's well known issue. Look here

http://boost.2283326.n4.nabble.com/range-cannot-use-lambda-predicate-in-adaptor-with-certain-algorithms-td3560157.html

Shortly, you should use this macro

#define BOOST_RESULT_OF_USE_DECLTYPE

for use decltype instead of boost::result_of.

Quote from here

If your compiler supports decltype, then you can enable automatic result type deduction by defining the macro BOOST_RESULT_OF_USE_DECLTYPE, as in the following example.

like image 30
ForEveR Avatar answered Sep 24 '22 03:09

ForEveR