error in std::transform

Hello there,

I get this error : term does not evaluate to a function taking 1 arguments.

Here is the code (relevant parts):

Grammer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
typedef std::vector<std::string> Value;
typedef std::vector<Value> ValueCollection;
typedef std::map<std::string,ValueCollection> Rules;
class Grammer
{
public:

	Grammer(){}
	Grammer(std::istream& in);

	std::string getCategory(std::string* line);

	std::string extractCollection(const std::string* category,const std::string* line);

	Value getValueCollection(std::string* line);

	Value getValue(std::string& line);

private:
	Rules rule; 
};


Grammer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
Grammer::Grammer(std::istream& in)
{
	std::string line;
	while(std::getline(in,line))
	{
		std::string category = getCategory(&line);
		line = extractCollection(&category,&line);
		Value entry = getValueCollection(&line);
	// herer the error occur
	
                std::transform(entry.begin(),entry.end(),
std::back_inserter(rule[category]), &Grammer::getValue);

	}
}

std::string Grammer::getCategory( std::string* line )
{
		std::string::iterator b,e;
		b = find_if(line->begin(),line->end(),not_space);
		e = find_if(line->begin(),line->end(), space);

		return std::string(b,e);
}

std::string Grammer::extractCollection( const std::string* category,const std::string* line )
{
	std::string::const_iterator b;
	b = std::search(line->begin(),line->end(),category->begin(),category->end());
	b = b+category->size();

	return std::string(b,line->end());
}

Value Grammer::getValueCollection( std::string* line )
{
	Value ret;
	split(line,"/",&ret);
	return ret;

}

Value Grammer::getValue( std::string& line )
{
	Value ret;
	split(&line," ",&ret);
	return ret;
}
Last edited on
You will have to wrap &Grammer::getValue to one of this helper function : http://www.cplusplus.com/reference/std/functional/
It will be one of the mem_fun_ref probably.
I'm just talking this out...
entry contains Value elements, So I assume the rule[category] is a contains containers who's elements are also Value. &Grammer::getValue takes an input of string, is a Value implicitly convertible to a string?
well entry is of type value i suppose when i make std::transform it loop throgh elements wich are std::string and getValue takes argument std::string & i think it is fine there isn't it?
What R0mai has said is correct, before I had even commented I produced code that used a non member function object instead of the member function operation and all worked, so I kind of cheated.

So either wrap it or just make something like:
1
2
3
4
5
6
7
8
9
struct get_value
{
    Value operator() (std::string & line)
   {
        Value ret;
        split(&line," ",&ret);
        return ret;
   }
};

Last edited on
But well i tried what he said and doesnt work i seem to get the same error but an extra line to it

class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments

thise is the substitution:
std::transform(entry.begin(),entry.end(),std::back_inserter(rule[category]), std::mem_fun_ref(&Grammer::getValue));
Try std::mem_fun1_ref. That should work.
Last edited on
Same
1
2
3
4
5
6
class foo{
public:
  type bar( buzz );
};

type bar( foo *this, buzz); //equivalent C form 
As you can see the method ask for 2 parameters.
You could make a wrapper as clanmjc showed
1
2
3
4
5
6
7
8
class wrapper{
public:
  Grammer &g; 
  wrapper( Grammer &g ): g(g) {}
  Value operator() (std::string & line){
    return g.getValue(line);
  }
};


Regarding your code, ¿why getCategory ask for a pointer but getValue for a reference?

By the way, ¿back_inserter gets ignored, right?
well I am not that good in c++ to know what u say up there :)

But when u told me it take 2 arguments i used
std::bind1st(std::mem_fun(&Grammer::getValue), this)



Do this:
1
2
3
4
5
6
7
8
9
struct get_value
{
    Value operator() (std::string & line)
   {
        Value ret;
        split(&line," ",&ret);
        return ret;
   }
};


And change the call to this:
std::transform(entry.begin(),entry.end(), std::back_inserter(rule[category]), get_value());

and be done with it (assuming all the elements are of the correct type as is the container returned by rule[category])

Edit: Or do what ne555 suggested and make the call like this:
std::transform(entry.begin(),entry.end(), std::back_inserter(rule[category]), wrapper(*this)());
Last edited on
Well I already did it with the std::bnd1st and it is working just fine but thank for help anyway. :)
Topic archived. No new replies allowed.