I keep on getting error message while trying to pass a function inside a for_each loop.. I have a vector and i used for_each loop to go through the rows in that vector, Now I need a function to do something
Example this is what I am trying to achieve:
void DataPartitioning::doSomething()
{
for_each (label.begin(), label.end(), addToTemporaryVector());
}
void DataPartitioning::addToTemporaryVector()
{
cout<<"sucess";
}
But I get an error message saying: error: invalid use of void expression both of them are in same class.
Since it's a member function, you'll need to wrap it in a functor that calls it on an object; presumably the same object that doSomething was called on:
for_each(label.begin(), label.end(), [this](whatever const &){addToTemporaryVector();});
where whatever is the value type of the container.
It might be clearer as a regular for-loop:
for (whatever const & thing : label) {
addToTemporaryVector();
}
This assumes you're not stuck with a pre-C++11 compiler. If you are, it requires rather more gibberish:
for_each(label.begin(), label.end(),
std::bind1st(std::mem_fun(&DataPartitioning::addToTemporaryVector), this));
I'm not entirely sure whether that will work with a function like yours that doesn't take an argument; but presumably your real code does take an argument to do something with each element.
You need to use a struct as here:
http://en.cppreference.com/w/cpp/algorithm/for_each
#include <iostream>
#include<string>
#include <vector>
#include <algorithm>
using namespace std;
struct Operation
{
void operator()(string n) { cout<<"success"<<endl; }
};
int main() {
vector<string> vInts(10,"abc");
std::for_each(std::begin(vInts), std::end(vInts), Operation());
// your code goes here
return 0;
}
Note that the input of the operator has to be the same as the type in the vector. (string in this example, int in the link)
The addToTemporaryVector function does not use this. So you can declare it as static.
Also, it should take as argument the template type of label
Declaration:
static void addToTemporaryVector(const SomeType & item);
Then just do:
//No parentheses to the function pointer
for_each (label.begin(), label.end(), addToTemporaryVector);
Related
Good Day everybody, I am creating a List class in order to be able to manipulate data like in python, but in c++.
I came up with an idea. Basically a method that goes through every node, and deletes it if it meets a specific condition. But I wanted that condition to be determined by the user of the library, so I implemented a pointer to a bool function, that takes one template data (same type as the List) as its only parameter.
So far, I managed to run this...
.h file:
int delIf(bool (*)(T));
.cpp file:
template <typename T>
int List<T>::delIf(bool (*ptr)(T)){
int tot=0;
T aux;
for (int i=0;i<tam;i++)
{
aux=(*this)[i]; //Ive overloaded the [], and it works fine
if ((*ptr)(aux))
{
tot++;
this->del(i);
}
}
return tot;
}
main.cpp:
#include <iostream>
#include "lists.cpp"
using namespace std;
bool check(int);
int main()
{
List<int> a;
for (int i=0;i<10;i++)
a.push(i);
a.delIf(&check);
return 0;
}
bool check(int a){
if (a%2==0)
return true;
else
return false;
}
This works fine, however, I was wondering if its possible to overload the delIf method so that it takes not a pointer to a function as parameter, but a reference to it, so the user of the library could call:
delIf(check); //No '&' required
Instead of the
delIf( & check);
That is currently mandatory. Ive tried changing the prototype to something like:
int delIf( (bool (*)(T)) & );
but I keep getting errors.
Thanks in Advance Everybody.
Your premise is false. You don't need an & in front of a function to pass it to delIf. The name of a function decays into a pointer to the function almost everywhere it is used in an expression. (Including when you call the function!) In fact, the only place it doesn't is when it is used as an argument to & - so
func
&func
have exactly the same type and value.
Having said that, yes you can pass a reference. First rule of pointers to functions - write a typedef
typedef bool pred_t(T);
void delIf( pred_t& pred );
But! I strongly encourage you to write delIf as a function template, and allow anything which can be called with a T, and has a function result which can be implicitly converted to bool.
template <typename Pred>
void delIf(Pred pred) {
...
}
That will allow use with capturing lambdas, and functors in general.
Also, what is this CPP file of which you speak? Templates have to be implemented in the header file. See the answers to this question.
(Note: "Pred" is short for "predicate" which is what the standard calls this sort of function.)
class f
{
public:
run(std::string method,std::string params)
{
...//call foo1 or foo2 with params by "method"
}
foo1(std::string a);
foo2(std::string a);
}
I'm trying to make a map<std::string,std::function<void(std::string)>> to implement it,but there is a error reported since the non-static member function needs a pointer to an instance.I'm not going to use function pointer like typdef f xxx,I preper to make a map between funcname and function.
Your approach is possible. You just need the correct prototype in std::function's definition.
std::map<std::string, std::function<void(f*, std::string)>> func_map;
The above will of course require that any member function you place here will return void and accept a std::string by value. No other prototypes will be admissible.
You can store the member pointers like this:
func_map["foo1"] = &f::foo1;
And then proceed to call them in run like so:
func_map[func_name](this, arg);
Ideally, func_map should be static. So you'd initialize it like so:
std::map<std::string, std::function<void(f*, std::string)>> f::func_map {
{"foo1", &f::foo1},
{"foo2", &f::foo2},
};
It's also worth-noting that you don't need to use std::function if all you want to store is pointers to members. Those can be stored directly. However, the flip side is that your approach allows for extendabilty!
Any free function which accepts f by pointer and a std::string by-value can be stored in the map as well.
You can solve it using this method:
#include <iostream>
#include <string>
#include <map>
#include <functional>
class f{
public:
std::map<std::string,std::function<void(f&,std::string)>> func_map{
{"foo1",[](auto& obj,std::string params){obj.foo1(params);} },
{"foo2",[](auto& obj,std::string params){obj.foo2(params);} }
}; // make static or accept inputs from outside the class
void run(std::string method,std::string params){
func_map.at(method)(*this,params); // treat exceptions as you want
}
void foo1(std::string a){std::cout << "foo1: " << a;}
void foo2(std::string a){std::cout << "foo2: " << a;}
};
int main(){
f fff;
fff.run("foo1","some_params");
fff.run("foo2","some_params");
}
Online Example
The only way in C++ is to switch on the string
if(method.compare"PrintButton")
classobj.PrintButton(atoi(params.c_str());
Strings are runtime objects, identifiers are compile time objects.
You can go the template route however to achieve much the same thing.
I'm a newbie to C++ and having an issue regarding std:map with function pointers.
I have created a map which has a string as the key and stored a function pointer as the value. I faced a complication when I tried to use insert() function to add a function pointer. However, it worked when I used [] operator. If you can, please explain this difference.
Here is a sample code I wrote.
OperatorFactory.h
#ifndef OPERATORFACTORY_H
#define OPERATORFACTORY_H
#include <string>
#include <map>
using namespace std;
class OperatorFactory
{
public:
static bool AddOperator(string sOperator, void* (*fSolvingFunction)(void*));
static bool RemoveOperator(string sOperator);
static void RemoveAllOperators();
private:
static map<string , void* (*) (void*)> map_OperatorMap;
};
// Static member re-declaration
map<string, void* (*) (void*)> OperatorFactory::map_OperatorMap;
#endif // OPERATORFACTORY_H
OperatorFactory.cpp
#include "OperatorFactory.h"
void OperatorFactory::RemoveAllOperators()
{
map_OperatorMap.clear();
}
bool OperatorFactory::RemoveOperator(string sOperator)
{
return map_OperatorMap.erase(sOperator) != 0;
}
bool OperatorFactory::AddOperator(string sOperator, void* (*fSolvingFunction)(void*))
{
// This line works well.
map_OperatorMap[sOperator] = fSolvingFunction;
// But this line doesn't.
// map_OperatorMap.insert(sOperator, fSolvingFunction); // Error
return true;
}
The Error says :
error: no matching function for call to 'std::map<std::basic_string<char>, void* (*)(void*)>::insert(std::string&, void* (*&)(void*))'
Even though I got this working (compiled) with the [] operator, I would like to know why I got an error when using insert().
Thank you.
You insert elements into std::map using a std::pair of the key and value:
map.insert(std::make_pair(key,value));
Alternatively you can emplace values in c++11:
map.emplace(key,value);
The [] operator returns a reference to the value for the key passed in:
value_type &
And automatically constructs an element for that key if it doesn't already exist. Make sure you understand what the difference in behavior is between insert() and the [] operator before using them (the latter will replace existing values for a key for example).
See http://en.cppreference.com/w/cpp/container/map for more information.
I am building a C++ program that needs to store a map of strings to function pointers. However, every function may have different return types and parameters. The way I am attempting to solve this problem is by creating the functions as taking an array of void pointers and returning an array of void pointers, and then casting the arguments and return values as needed.
To figure out how this would work, I'm trying to build a simple dummy, but can't get it to compile. I've tried a number of things, but I keep getting different errors. here's an example:
#include <string>
#include <iostream>
#include <map>
using namespace std;
void** string2map(void** args){
//takes a string of the form "key:value;key:value;..." and returns a map<string,string>
string st = *((string**) args)[0];
map<string, string> result = map <string, string>();
//code doesnt matter
return (void*) &((void*) &result);
}
int main(){
string test = "hello:there;how:are you?";
map<string, string> result = *(map<string, string>**)string2map((void*) &((void*) &test))[0];
return 0;
}
when I try to compile, I get:
void.cpp: In function 'void** string2map(void**)':
void.cpp:12:34: error: lvalue required as unary '&' operand
void.cpp: In function 'int main()':
void.cpp:17:89: error: lvalue required as unary '&' operand
Obviously there are plenty of things wrong here, but I really just don't know where to start. Can anyone either show me what's wrong with the code above, or give me an alternative to the way I am currently doing it?
NOTE
The reason I am returning a void** instead of just void* is that there might be a circumstance where I need to return multiple values of different types. An example would be if, above, I wanted to return both the resulting map AND the number of entries in the map. I haven't even gotten to the point of figuring out how to construct that array yet, though.
EDIT
So based on the responses so far, it seems pretty clear that this is the wrong way of solving this problem. With that in mind, can anyone suggest a better one? I need to be able to store the various function in a single map, which means I need to be able to define a single data type to functions that take and return different types. And it IS important to be able to return multiple values.
You're converting a map<string,string> to a void**, returning it then converting it back to a map<string,string. Why not just return a map<string,string>? It's also called string2map which implies you will only ever call it with a string (backed up by the fact you pass in a string, which is converted to a void** then converted straight back). Unless you have a good reason to convert to and from void** all over the place this is probably what you need:
#include <string>
#include <iostream>
#include <map>
using namespace std;
map<string, string> string2map(string st){
map<string, string> result = map <string, string>();
//code doesnt matter
return result;
}
int main(){
string test = "hello:there;how:are you?";
map<string, string> result = string2map(test);
return 0;
}
EDIT:
I've just reread your question. You might want to look up Generalised Functors and look at Boost's std::function as possible solutions to this problem. It's possible to change the return type of a function via a wrapper class, something like:
template< class T >
class ReturnVoid
{
public:
ReturnVoid( T (*functor)() ) : m_functor( functor ) {}
void operator() { Result = functor(); }
private:
T (*m_functor)();
T Result;
};
// Specialise for void since you can't have a member of type 'void'
template<>
ReturnVoid< void >
{
public:
ReturnVoid( T (*functor)() ) : m_functor( functor ) {}
void operator() { functor(); }
private:
T (*m_functor)();
};
Using this as a wrapper might help you store functors with different return types in the same array.
Ignoring my own horror at the idea of blatantly throwing type safety to the wind, two things spring immediately to mind.
First, what exactly do you think will be pointed to when string2map goes out of scope?
Second is that you don't have to cast to void*. Void* gets special treatment in C++ in that anything can be cast to it.
If you insist on trying to push this, I'd start by changing the return type to void, and then take the void* as an input parameter to your function.
For example:
void string2map(void* args, void* returnedMap);
This way you'd have to instantiate your map in a scope that will actually have a map to point to.
$5.3.1/3 - "The result of the unary & operator is a pointer to its
operand. The operand shall be an lvalue or a qualifiedid."
$5.3.1/2 - "The result of each of the following unary operators is a
prvalue."
So, in effect you are trying to take the address of an rvalue which is not allowed.
Further, C++ does not allow to return an array.
So, you really want to start looking at what you want. Return the map by value instead is one definite option.
The way I am attempting to solve this problem is by creating the functions as taking an array of void pointers and returning an array of void pointers, and then casting the arguments and return values as needed.
That's (really really) bad. Have a look instead at std::function and std::bind - those should cover differences between function signatures and bound arguments in an elegant way.
The reason I am returning a void** instead of just void* is that there might be a circumstance where I need to return multiple values of different types.
Then return an object that contains the values. For generics have a look at std::tuple or boost::any.
Here's some code:
void function1(int, const char); // defined elsewhere
std::tuple<int,int> function2(std::string&); // defined elsewhere
std::map<std::string,std::function<void(void)>> functionmap;
functionmap.insert( std::make_pair("function1", std::bind(&function1, 2, 'c')) );
std::tuple<int,int> result;
functionmap.insert( std::make_pair("function2", [&result] {
result = function2("this is a test"); } );
// call function1
functionmap["function1"]();
// call function2
functionmap["function2"](); // result will now contain the result
// of calling function2
Is this what you tried to do?
int Foo(int a) { return a; }
typedef int (*FooFunc)(int);
void Bar(){}
typedef std::map<std::string, void*> FunctionMap;
// you should use boost::any or something similar instead of void* here
FunctionMap CreateFunctionMap(const std::string& args)
{
FunctionMap result;
result["Foo"] = &Foo;
result["Bar"] = &Bar;
return result;
}
void Call(FunctionMap::const_reference functionInfo)
{
// #hansmaad The key will give information on the signatures.
// there are a few distinct options, so it will be a conditional
// with a couple of clauses.
if (functionInfo.first == "Foo")
{
auto f = static_cast<FooFunc>(functionInfo.second);
std::cout << f(42);
}
else if (functionInfo.first == "Bar")
{
/* */
}
}
int main()
{
auto functions = CreateFunctionMap("...");
std::for_each(begin(functions), end(functions), Call);
}
#hansmaad The key will give information on the signatures. there are a few distinct options, so it will be a conditional with a couple of clauses. – ewok 33 mins ago
In that case, the typical solution is like this:
typedef void (*func_ptr)();
std::map<std::string, func_ptr> func_map;
map<string,string> string2map(string arg){
//takes a string of the form "key:value;key:value;..." and returns a map<string,string>
map<string, string> result = map <string, string>();
//...
return result;
}
// ...
// Add function to the map
func_map["map<string,string>(string)" = (func_ptr)string2map;
// Call function in the map
std::map<std::string, func_ptr>::iterator it = ...
if (it->first == "map<string,string>(string)")
{
map<string,string> (*func)(string) = (map<string,string>(*)(string))it->second;
map<string,string> result = func("key1;value1;key2;value2");
}
For brevity, I have used C-style casts of the function pointers. The correct C++ cast would be reinterpret_cast<>().
The function pointers are converted to a common type on insertion into the map and converted back to their correct type when invoking them.
I have a class Test with a peculiar data structure.
A member of class Test is a std::map where the key is a std::string and the mapped value is a struct defined as follows:
typedef struct {
void (Test::*f) (void) const;
} pmf_t;
Initialization of the map is OK. The problem is when I am trying to call the function pointed. I made up a toy example reproducing the problem. Here it is:
#include <iostream>
#include <map>
using namespace std;
class Test;
typedef void (Test::*F) (void) const;
typedef struct {
F f;
} pmf_t;
class Test
{
public:
Test () {
pmf_t pmf = {
&Test::Func
};
m["key"] = pmf;
}
void Func (void) const {
cout << "test" << endl;
}
void CallFunc (void) {
std::map<std::string, pmf_t>::iterator it = m.begin ();
((*it).second.*f) (); // offending line
}
std::map<std::string, pmf_t> m;
};
int main ()
{
Test t;
t.CallFunc ();
return 0;
}
Thanks in advance,
Jir
The name of the pmf_t type is f, so the first change is to remove the * to get second.f. That gives you a pointer-to-member value. To use a pointer-to-member, you need an instance. The only one you have available of the correct type is this, so use it with the ->* operator:
(this->*it->second.f)();
You need parentheses around the whole thing, or else the compiler thinks you're trying to call it->second.f() (which isn't allowed) and then applying the result to ->*.
The offending line is trying to call a member function without any object to call it on. If the intention is to call it for the this object, I believe the call should look like
( this->* ((*it).second.f) )();
Where this->* is the syntax for dereferencing a pointer-to-member for the current object. ((*it).second.f) is the pointer retrieved from the map, and () is the call operator for actually calling the function.
This is perhaps good as an exercise, but otherwise of limited use.
I think you might want to check out the C++ FAQ on this one. The syntax is apparently pretty tricky to get right (they actually recommend using a macro).
It might be too late for this question but, the seemingly complex synatax can be break down to two simple lines so it looks pretty clear:
void CallFunc (void)
{
pmf_t t = m["key"]; //1>get the data from key
(this->*t.f)(); //2>standard procedure to call pointer to member function
}
try this:
(this->*((*it).second.f)) ();