2

I would like to remove an object from a vector based on a lambda predicate:

class tmr
{
public:
  tmr();
  ~tmr();
  static void start();
  bool is_time_out(double sec);
  double t_elapsed();
};

struct sobj
{
  int count;
  bool tflag;
  int ID;
  tmr timer;
  friend bool is_stime(timer& objtimer,double sec)
   {
    return objtimer.is_time_out(sec);
   }
};

somewhere in the main program, I populate a vector<sobj>, then after some time, I want to remove the element whose ID is specified and whose timer has elapsed.

I did this , and it complains about not being able to convert void to bool

sobj strobj;
vector<sobj> vecobj;

vecobj.erase(std::remove_if(vecobj.begin(),vecobj.end(),[&](const sobj& mysobj){return ( mysobj.ID== THE_ID && mysobj.is_stime(mysobj.timer,5));}),vecobj.end());
Useless
  • 64,155
  • 6
  • 88
  • 132
Sam Gomari
  • 733
  • 4
  • 13
  • 37
  • Could you show your compiler, its version, and paste the actual error? – Useless Apr 02 '15 at 15:36
  • @Useless: The unhelpful part is that Sam didn't include this part of the error: `foo.cc:11:16: error: use of undeclared identifier 'is_sobj'` – Bill Lynch Apr 02 '15 at 15:49
  • Can you post the actual error message, instead of your interpretation of it? highlight, copy, paste into text editor, add 4 spaces at front of each line (`s/^/ /` assuming your editor is vi), and edit it into your post. – Yakk - Adam Nevraumont Apr 02 '15 at 16:03
  • first, the compiler is C++11. I did what's recommended in the answer , the error is : error: passing ‘const timer’ as ‘this’ argument of ‘bool timer::is_time_out(double)’ discards qualifiers [-fpermissive] return to.obj_timer.is_time_out(sec); – Sam Gomari Apr 02 '15 at 16:04
  • ok, i'll post the output, i just need to edit it, am unable to disclose some output information – Sam Gomari Apr 02 '15 at 16:08
  • @SamGomari: That's when you create a self contained, minimal test case! – Bill Lynch Apr 02 '15 at 16:20

2 Answers2

4

First things first:

Let's note that this has very little to do with the lambda. The following code will also fail to compile:

sobj strobj;
is_stime(strobj.timer, 5);

Steps taken:

  1. Let's reduce your test case down..
  2. is_stime() needs to take a const reference, or your lambda needs to pass a non-const reference.
  3. is_stime() is not visible to your lambda. Would you like to know more?

Reduced Code:

#include <iostream>
#include <vector>
using namespace std;

int THE_ID;

class tmr {
};

struct sobj {
    int ID;
    tmr timer;

    friend bool is_stime(tmr const & objtimer, double sec);
};

bool is_stime(tmr const & objtimer, double sec) {
    return true;
}

int main() {
    vector<sobj> vecobj;
    vecobj.erase(std::remove_if(vecobj.begin(),vecobj.end(),[&](const sobj& mysobj){return ( mysobj.ID == THE_ID && is_stime(mysobj.timer,5));}),vecobj.end());
}
Community
  • 1
  • 1
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • Is it possible to render "is_time_out(double sec)" of tmr class accessible/visible to lambda function, i can bypass struct's friend function – Sam Gomari Apr 02 '15 at 16:23
  • @SamGomari: I'm sorry, I don't understand what you mean. – Bill Lynch Apr 02 '15 at 16:34
  • you can see that tmr class has a function "is_time_out" , and since tmr object is a member of the sobj struct , i was wondering if one can simply have the lambda return the result of the "is_time_out" , without sobj having to have a function. Just directly access member function of tmr and return its result from lambda function to remove it from vector. – Sam Gomari Apr 02 '15 at 16:39
  • @SamGomari: I don't see any reason why you couldn't do that. – Bill Lynch Apr 02 '15 at 16:48
  • The issue was the const in [&](const sobj& mysobj){return ... } . Thanks a lot – Sam Gomari Apr 02 '15 at 18:59
1

your lambda is missing a return type:

[&](const sobj& mysobj)->bool
Useless
  • 64,155
  • 6
  • 88
  • 132
shoosh
  • 76,898
  • 55
  • 205
  • 325
  • 1
    Shouldn't this take care of it: [_if the body consists of nothing but a single return statement with an expression, the return type is the type of the returned expression (after rvalue-to-lvalue, array-to-pointer, or function-to-pointer implicit conversion)_](http://en.cppreference.com/w/cpp/language/lambda) – Bill Lynch Apr 02 '15 at 15:28
  • not sure the missing return is the issue, seems that even the single-return statement was relaxed, see e.g http://stackoverflow.com/questions/28955478/when-can-we-omit-the-return-type-in-a-c11-lambda – vsoftco Apr 02 '15 at 15:33
  • I do not think the return type is the issue. – Sam Gomari Apr 02 '15 at 16:09