I have the below code, where a class is trying to take one of two std::function signatures through its constructor. I'm able to get the signature that has the double parameter to compile, but the parameter-less signature fails to compile, saying the call is ambiguous.
#include <functional>
class Foo
{
public:
void baz(double value) {
}
};
class Bar
{
public:
void baz() {
}
};
class Overloader {
public:
Overloader(std::function<void(double)> inFuncWithArg)
: funcWithArg(inFuncWithArg)
{
}
Overloader(std::function<void(void)> inFuncNoArg)
: funcNoArg(inFuncNoArg)
{
}
private:
std::function<void(double)> funcWithArg;
std::function<void(void)> funcNoArg;
};
int main()
{
Foo foo;
Bar bar;
// Compiles
Overloader overloader1(std::bind(static_cast<void(Foo::*)(double)>(&Foo::baz)
, &foo, std::placeholders::_1));
// Fails to compile - "call of overloaded ‘Overloader(std::_Bind_helper::type)’ is ambiguous"
Overloader overloader2(std::bind(static_cast<void(Bar::*)(void)>(&Bar::baz)
, &bar));
return 0;
}
What am I missing that's causing this to fail? Also, are there any less-verbose ways to do this?
Here's the full error output
main.cpp: In function ‘int main()’:
main.cpp:51:20: error: call of overloaded ‘Overloader(std::_Bind_helper::type)’ is ambiguous
, &bar));
^
main.cpp:32:5: note: candidate: Overloader::Overloader(std::function)
Overloader(std::function<void(void)> inFuncNoArg)
^~~~~~~~~~
main.cpp:27:5: note: candidate: Overloader::Overloader(std::function)
Overloader(std::function<void(double)> inFuncWithArg)
^~~~~~~~~~
This question is more about std::bind than std::function.
The result of the expression
std::bind(&Foo::baz, &foo, std::placeholders::_1)
is invocable with one or more arguments, where the first argument is convertible to double.
The result of the expression
std::bind(&Bar::baz, &bar)
is invocable with zero or more arguments, with no restrictions.
The first expression can thus only initialize std::function<void(double)>, but the second expression can initialize either std::function<void(double)> or std::function<void(void)> and is ambiguous.
Genuinely, do not use std::bind. You can use std::bind_front if you have it. Alternatively, use a lambda.
std::bind_front:
std::bind_front(&Foo::baz, &foo)
std::bind_front(&Bar::baz, &bar)
lambda:
[&foo](double) { foo.baz(value); }
[&bar] { bar.baz(); }
Just use a lambda:
auto overloader1 = [&foo](double value) { foo.baz(value); };
auto overloader2 = [&bar]() { bar.baz(); }
I'd like to create a class where the client can store a lambda expression like []() -> void {} as a field of the class, but I can't figure out how to do so. One answer suggested using decltype, which I tried with no success. Here is a ideone source link. The below is the source and result:
#include <cstdio>
auto voidLambda = []()->void{};
class MyClass {
public:
decltype(voidLambda) t;
MyClass(decltype(voidLambda) t) {
this->t = t;
}
};
int main() {
MyClass([] {
printf("hi");
});
}
Result:
prog.cpp: In constructor 'MyClass::MyClass(<lambda()>)':
prog.cpp:3:79: error: no matching function for call to '<lambda()>::__lambda0()'
prog.cpp:2:20: note: candidates are: <lambda()>::<lambda>(const<lambda()>&)
prog.cpp:2:20: note: <lambda()>::<lambda>(<lambda()>&&)
prog.cpp:3:88: error: no match for 'operator=' in '((MyClass*)this)->MyClass::t = t'
prog.cpp: In function 'int main()':
prog.cpp:5:27: error: no matching function for call to 'MyClass::MyClass(main()::<lambda()>)'
prog.cpp:3:48: note: candidates are: MyClass::MyClass(<lambda()>)
prog.cpp:3:14: note: MyClass::MyClass(const MyClass&)
Does anyone know how to do this?
If you want a class member to be a lambda expression, consider using the std::function<> wrapper type (from the <functional> header), which can hold any callable function. For example:
std::function<int()> myFunction = [] { return 0; }
myFunction(); // Returns 0;
This way, you don't need to know the type of the lambda expression. You can just store a std::function<> of the appropriate function type, and the template system will handle all the types for you. More generally, any callable entity of the appropriate signature can be assigned to a std::function<>, even if the the actual type of that functor is anonymous (in the case of lambdas) or really complicated.
The type inside of the std::function template should be the function type corresponding to the function you'd like to store. So, for example, to store a function that takes in two ints and returns void, you'd make a std::function<void (int, int)>. For a function that takes no parameters and returns an int, you'd use std::function<int()>. In your case, since you want a function that takes no parameters and returns void, you'd want something like this:
class MyClass {
public:
std::function<void()> function;
MyClass(std::function<void()> f) : function(f) {
// Handled in initializer list
}
};
int main() {
MyClass([] {
printf("hi")
}) mc; // Should be just fine.
}
Hope this helps!
The only way I can think of to store a lambda in a class is to use a template with a helper make_ function:
#include <cstdio>
#include <utility>
template<class Lambda>
class MyClass {
Lambda _t;
public:
MyClass(Lambda &&t) : _t(std::forward<Lambda>(t)) {
_t();
}
};
template<class Lambda>
MyClass<Lambda> make_myclass(Lambda &&t) {
return { std::forward<Lambda>(t) };
}
int main() {
make_myclass([] {
printf("hi");
});
}
In case of [] (empty capture) simple function pointer can be used. Declaration syntax is ReturnType (*pointer_name) (Arg1T, Arg2T); for pointer, ReturnType (&ref_name) (/*void*/); for reference (can't be null). Lambda with empty capture block is implicitly convertible to function pointer with same signature. And std::function have runtime and size (it is at least three times larger) overhead.
struct S
{
void (*f_p)() {}; // `{}` means `= nullptr`;
};
int main()
{
S s { [] { std::cout << "Lambda called\n"; }};
s.f_p();
S s2;
if (s2.f_p) // check for null
s.f_p();
s2.f_p = [] { std::cout << "Lambda2 called\n"; };
s2.f_p();
s2.f_p = std::terminate; // you can use regular functions too
s2.f_p();
}
Output
Lambda called
Lambda2 called
terminate called without an active exception
I want to pass a class method to another function and I wrote these codes:
class x {
executeQuery(std::string query, int (*f)(void* cpuInfo, int argc, char** argv, char** azColName))
{
int rc = sqlite3_exec(db, query.c_str(), &f, 0, &errMessage);
...
}
};
The above code shows the function that I called from class constructor!
myclass()
{
xObject->executeQuery("test", &(myclass::myfunction));
}
And this part of code shows how I pass myfunction to that method! But, during compile time I got this error:
error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.
I called a thread constructor by same syntax! But it sounds like that the thread constructor makes a new function pointer that I can't understand! Do you have any idea how I can solve this problem with/without thread solution?
The below code shows the thread constructor header:
template<typename _Callable, typename... _Args>
explicit
thread(_Callable&& __f, _Args&&... __args)
{
_M_start_thread(_M_make_routine(std::__bind_simple(
std::forward<_Callable>(__f),
std::forward<_Args>(__args)...)));
}
Update:
In your example you use the function pointer with sqlite3_exec. sqlite3_exec requires a C-style function as argument callback. You can not use a pointer to a class member function here!
Something like this might be a work-around. But beware of thread-safty:
namespace wrap {
typedef std::function<int(void*,int,char**,char**)> QueryFunction;
inline QueryFunction& function() {
static QueryFunction f;
return f;
}
void callback(void* cpuInfo, int argc, char** argv, char** azColName);
}
void wrap::callback(void* cpuInfo, int argc, char** argv, char** azColName) {
function()(cpuInfo, argc, argv, azColName);
}
class x {
executeQuery(std::string query, QueryFunction f)
{
wrap::function() = f;
int rc = sqlite3_exec(db, query.c_str(), &wrap::callback, 0, &errMessage);
...
}
};
MyClass* obj = ...;
xObject->executeQuery("test", std::bind(myclass::myfunction, obj));
Old answer:
You can use std::function to wrap class member functions (see here):
#include <functional>
typedef std::function<int(void*,int,char**,char**)> QueryFunction;
class x {
public:
void executeQuery(std::string query, QueryFunction f) {
f(ptr,0,"hello","test"); // call function
}
};
MyClass* obj = ...;
using std::placeholders;
xObject->executeQuery("test", std::bind(myclass::myfunction, obj, _1, _2, _3, _4));
In order to give a pointer to a class member function, you need to also provide an object on which the member function should be called.
std::bind allows you to do this (and even more). In the case above, the first argument to std::bind is the pointer to the class member function and the second argument is the object which shall be used to call the function. The following arguments _1, ... are placeholders for arguments you will provide later when using the function pointer.
std::thread and many other libraries don't receive function pointer. They receive functor.
functor is all things which can be called with () operator. So, function pointer is functor:
void (*pf)();
// we can do it
pf();
We also can call the object which overloads operator ().
struct Functor
{
void operator ()();
};
Funtor f;
// we also can do it
f();
Member function pointer is not functor. (you can't mpf(this);. this->*mpf(); is correct.) However, the constructor of std::thread performs bind.
For example:
#include <iostream>
#include <functional> // for std::bind
template <typename F>
void call_functor(F f)
{
f();
}
void foo() { std::cout << "foo\n"; }
struct bar { void operator ()() { std::cout << "bar\n"; } };
void WithParam(int i) { std::cout << "param : " << i << "\n"; }
class Cls
{
public:
void member() { std::cout << "Cls::member\n"; }
};
int main()
{
// we can do these, because both foo and b are functor.
bar b;
call_functor(foo);
call_functor(b);
// bind `123`
call_functor(std::bind(WithParam, 123));
// bind `c`
Cls c;
call_functor(std::bind(&Cls::member, &c /* this pointer */));
}
Look this: call_functor(std::bind(WithParam, 123));. Although WithParam cannot be called with f() because it has a parameter, we can use WithParam by binding its parameter to 123.
std::bind can perform not only binding parameter, but also binding this pointer with member function pointer. So we also can do this: call_functor(std::bind(&Cls::member, &c /* this pointer */));.
We cannot know the type of all functors. For example: void (*)(), struct bar, or std::bind...
So, to receive functor as parameter, we should use template. For example, look at std::thread's constructor:
template<typename _Callable, typename... _Args>
explicit
thread(_Callable&& __f, // <-- here
...
In your case, you should do like this:
class x
{
public:
template <typename Functor>
void executeQuery(std::string query, Functor f)
{
...
int result = f(cpuInfo, argc, argv, azColName);
...
}
};
...
myclass()
{
xObject->executeQuery("test", std::bind(&myclass::myfunction, this));
}
Do you mind use template (Maybe you want to hide the implementation of executeQuery)? Then, there's another solution, std::function<>. it's polymorphism-wrapper to functor. It is a little slower than functor, but it can be good solution if you mind use template.
class x
{
public:
void executeQuery(std::string query,
const std::function<int ()(void*, int, char**, char**)> &f);
};
Usage is almost equal to functor. (maybe you need to explicit-cast into std::function<>) In fact, std::function is functor, too! (it can be called with () operator..)
edit: Ummm.. I've just noticed you're using f like this:
int rc = sqlite3_exec(db, query.c_str(), &f, 0, &errMessage);
Maybe the third parameter of sqlite3_exec is function pointer, right? It'll become complicated..
According to here, the 4th argument of sqlite3_exec will be passed into f as the 1st argument. Then, we can write code like this:
// header file of `class x`
class x
{
private:
static void ExecuteQuery_Callback(void *param, int argc, char** argv, char** azColName);
// use std::function<>
typedef std::function<int (void*, int, char**, char**)> ExecQueryFunctor;
void executeQuery_impl(std::string query, const ExecQueryFunctor &f);
public:
// wrapper
template <typename F> void executeQuery(std::string query, F f)
{
executeQuery_impl(query, ExecQueryFunctor(f));
}
};
// .cpp file of `class x`
void x::executeQuery_impl(std::string query, const x::ExecQueryFunctor &f)
{
int rc = sqlite3_exec(db, query.c_str(), ExecuteQuery_Callback, &f, &errMessage);
...
}
void x::ExecuteQuery_Callback(void *param, int argc, char** argv, char** azColName)
{
const ExecQueryFunctor *pfunctor = (const ExecQueryFunctor *)param;
(*pfunctor)(NULL, argc, argv, azColName);
}
edit2: Um, I see the problem.. For one thing, it works well if you do this:
xObject->executeQuery("test", std::bind(&myclass::myfunction, this));
Change into:
using namespace std::placeholders;
...
xObject->executeQuery("test", std::bind(&myclass::myfunction, this, _1, _2, _3, _4));
_1, _2, _3, _4 are placeholders. (If you want to know about placeholders, search google..)
In this case, I don't think placeholders are required, But if there's no placeholders, error occurs...
edit3: the reason of why we should use placeholders: Why are placeholders required in std::bind in this case?
After much hanging around and trying out possible solutions, I found that there is no solution for my problem. I had a conversation with a professional c++ programmer(Hedayat Vatankhah) and he explained since a method of a class has a special address in c++, you can't pass its pointer to a c function (like sqlite3_exec) that expect an absolute address.
BTW, it sounds like that there is an extension for gcc that can convert method address to absolute address (but I leave this solution and I try some simple sqlite3 function to create new version of sqlite3_exec)
#include <functional>
struct A
{
int func(int x, int y)
{
return x+y;
}
};
int main()
{
typedef std::function<int(int, int) > Funcp;
A a;
//Funcp func = std:::bind(&A::func, &a);
Funcp func = std::bind(&A::func, a, std::placeholders::_1);
return 0;
}
I am getting errors in both of the above bind functions:
error C2825: '_Fty': must be a class or namespace when followed by '::'
Where is the syntax error? I am using visual studio 2010
Funcp func =
std::bind(&A::func, &a, std::placeholders::_1, std::placeholders::_2);
It took a while for me to figure out what's happening. So adding it here for the benefit of others, where an explanation would help. I've renamed some functions and variables for more clarity.
#include <functional>
struct A
{
int MemberFunc(int x, int y)
{
return x+y;
}
};
int main()
{
typedef std::function<int(int, int)> OrdinaryFunc;
A a;
OrdinaryFunc ofunc = std::bind(&A::MemberFunc, a, std::placeholders::_1, std::placeholders::_2);
int z = ofunc(10, 20); // Invoke like an ordinary function
return 0;
}
Class member functions have an implicit/hidden parameter which points to the object (this pointer). These member functions can be invoked only by providing an object, which makes it different from an ordinary function.
std::bind can be used to "convert" a member function into an ordinary function by passing the object (pointer or reference). It has be the first argument in the list of args (&a or a in this case) following the member function. In the new function, the object is bound to the implicit/hidden parameter of the member function, and need not be passed when invoked. The unbound arguments are represented by the placeholders _1, _2 and have to be passed when invoked.
What's wrong with the following little program that passes a function object?
#include <iostream>
#include <functional>
void foo(const std::unary_function<const std::string&, void>& fct) {
const std::string str = "test";
fct(str); // error
}
class MyFct : public std::unary_function<const std::string&, void> {
public:
void operator()(const std::string& str) const {
std::cout << str << std::endl;
}
};
int main(int argc, char** argv){
MyFct f;
foo(f);
return 0;
}
I'm getting the following error in line 6:
no match for call to
`(const std::unary_function<const std::string&, void>) (const std::string&)'
A common mistake. unary_function and binary_function are just two structs that add typedefs
argument_type
result_type
and respectively
first_argument_type
second_argument_type
result_type
Not more. They are for convenience of creators of function object types, so they don't have to do those themselves. But they don't behave polymorphic. What you want is function object wrapper. boost::function comes to mind:
void foo(boost::function<void(const std::string&)> const& fct) {
const std::string str = "test";
fct(str); // no error anymore
}
Or make it a template
template<typename FunctionObject>
void foo(FunctionObject const& fct) {
const std::string str = "test";
fct(str); // no error anymore
}
You can take it by value and then return the copy from foo if use it to apply it to some sequence. Which would allow the function object to update some state variables among its members. for_each is an example that does it like that. Generally, anyway, i would accept them by value because they are usually small and copying them allows greater flexibility. So i do
template<typename FunctionObject>
void foo(FunctionObject fct) {
const std::string str = "test";
fct(str); // no error anymore
}
You will then be able to take a copy of fct and save it somewhere, and fct's operator() can be non-const and update some members (which is part of the whole point of operator()). Remember if you take a function object by const reference, you can't generally copy it, because the user could have passed a function. Copying it then will try to locally declare a function instead of a local function pointer. However, accepting by-value will accept a function pointer instead when a function was passed, which can safely be copied.