In this example, I have a pointer of function (std::function) as an attribute of my class. So I can associate any function of the form void myFunction(void) to my class.
#include <iostream>
#include <functional>
class Example{
private:
int variable=4;
public:
std::function<void(void)> myNonMemberFunction;
Example(void){
}
Example(std::function<void(void)> MyNonMemberFunction){
myNonMemberFunction=MyNonMemberFunction;
}
};
void PrintPlop(){
std::cout<<"plop"<<std::endl;
}
int main() {
Example example(PrintPlop);
example.myNonMemberFunction();
}
Now, I want to do the same but with a function which has accessed to the class attribute like a friend function or a class-member function. How can I do this?
So you want any function you pass to the constructor become a friend?
In the strict sense it is impossible, because the access level (friend or not) is a compile-time issue, and which value is passed to the constructor, generally speaking, is determined only in run-time.
So you either declare all the relevant functions as friends (why not just make them methods in this case?) or pass the private members to them as additional parameters. Like this:
class Example{
private:
int variable=4;
std::function<void(int)> myNonMemberFunction;
public:
Example(void){
}
Example(std::function<void(int)> MyNonMemberFunction){
myNonMemberFunction=MyNonMemberFunction;
}
void callMyNonMemberFunction() {
myNonMemberFunction(variable);
}
};
void PrintPlop(int v){
std::cout<<"plop"<< v << std::endl;
}
int main() {
Example example(PrintPlop);
example.callMyNonMemberFunction();
}
Assume that I wanted to debug the following simple program. And that I want to define a breakpoint in the function bar().
#include <iostream>
void bar() {
std::cout << "Hello" << std::endl;
}
void foo() {
bar();
}
int main(int argc, char** args) {
bar();
foo();
return 0;
}
As a function might be called a lot of times in a real world example, I only wanted the debugger to stop if bar() was called inside foo(). So that the debugger will stop only once in the given example.
It should look like CALLER_FUNCTION=foo(), where foo() should be found somewhere in the stack backtrace.
Is it possible in MSVC2010 to define a conditional breakpoint that has this specific behavior?
I was trying to work on the below code but the program crashes:
#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef void (*callBackMethod)(string);
class CTest
{
private:
map<string, callBackMethod> mapMethod;
void testMethod(string msg)
{
cout << msg << endl;
}
public:
CTest()
{
addFunction("AA", (callBackMethod) &CTest::testMethod);
}
void addFunction(string funName, callBackMethod methodName)
{
mapMethod[funName] = methodName;
}
callBackMethod getMethod(string funName)
{
auto fun = mapMethod.find(funName);
if(fun == mapMethod.end()) { return nullptr; }
return fun->second;
}
void runFunction(string funName)
{
getMethod(funName)("test");
}
};
int main()
{
CTest test;
test.runFunction("AA");
return 0;
}
I have a requirement where I need to pass private methods to a map. The program compiles with warning:
converting from 'void (CTest::*)(std::__cxx11::string) {aka void (CTest::*)(std::__cxx11::basic_string<char>)}' to 'callBackMethod {aka void (*)(std::__cxx11::basic_string<char>)}'
and when I execute this, it crashes.
When I move the callback method outside of the class it works. My requirement is to make the program flow this was (hide the methods from external call which needs to be added to a map).
Looking forward to your comments.
If you need to point to both CTest member functions and free functions, then you can use std::function<void(std::string)>.
#include <iostream>
#include <string>
#include <map>
#include <functional>
using namespace std;
using callBackFunction = std::function<void(string)>;
void testFunction(string msg)
{
cout << "[" << __PRETTY_FUNCTION__ << "] " << msg << endl;
}
class CTest
{
private:
map<string, callBackFunction> mapMethod;
void testMethod(string msg)
{
cout << "[" << __PRETTY_FUNCTION__ << "] " << msg << endl;
}
public:
CTest()
{
addFreeFunction("AA", testFunction);
addMemberFunction("BB", &CTest::testMethod);
}
void addMemberFunction(string funName, void(CTest::*methodName)(string))
{
using std::placeholders::_1;
mapMethod[funName] = std::bind(methodName, this, _1);
}
void addFreeFunction(string funName, void(*methodName)(string))
{
mapMethod[funName] = methodName;
}
callBackFunction getMethod(string funName)
{
auto fun = mapMethod.find(funName);
if(fun == mapMethod.end()) { return nullptr; }
return fun->second;
}
void runFunction(string funName)
{
getMethod(funName)("test");
}
};
int main()
{
CTest test;
test.runFunction("AA");
test.runFunction("BB");
return 0;
}
Notice that CTest must insert elements into the map in a different way depending on what type of function you are passing, since for member functions you must provide the object for which it is to be invoked, this in this example. This is achived by using std::bind.
Since you want to use member variables you need to specify the signature differently in your typedef:
In C++ Builder the following can be done:
typedef void(__closure *callBackMethod)(string);
If you do that, I do suggest that you keep a smart pointer to the object that the member belongs to so that you can check if the object is still valid before calling the function otherwise it will crash the application.
The __closure keyword is a C++ Builder extension to work around the requirement to use fully qualified member names source
To handle both global and member functions we have the following:
typedef void(__closure *callBackMethodMember)(string);
typedef void (*callBackMethodGlobal)(string);
/* And then on 2 overloaded functions */
void addFunction(string funName, callBackMethodMember methodName) {}
void addFunction(string funName, callBackMethodGlobal methodName) {}
//main.c
#include "stdio.h"
void f(){
printf("Welcome to emacs's world!");
return;
}
void call_f(void (*f)()){
(*f)();
return;
}
void main(){
call_f(f);
return;
}
I use cscope to find the definition of function "call_f", but have no result, the cscope can't find the definition of "call_f".
I change the argument type of function "call_f" to another type except for a function pointer.
#include "stdio.h"
void f(){
printf("Welcome to emacs's world!");
return;
}
void call_f(/* void (*f)() */void){
// (*f)();
f();
return;
}
void main(){
// call_f(f);
call_f(void);
return;
}
Then cscope can find the definition of function "call_f".
Is that a bug?
Yes, this is a bug. Cscope doesn't implement a full C language parser. Instead it just uses a scanner with a lot of quirks.
For example, cscope also isn't able to recognize function calls/declarations if the opening argument bracket is on the next line like this:
fn_foo
(arg1, arg2);
The bug you found is even documented in cscope's man page:
Nor does it recognize function definitions with a function pointer
argument
ParseTable::Recognize(int startState, char *pattern,
int finishState, void (*FinalAction)(char *))
{
...
}
need a function wrapper for std::bind that will be called before the function it's wrapper, passing the arguments along to the wrapped functions.
std::function<void (int)> foo = postbind<int>(service, handle);
That's as far as I've got too. I'd like to make the postbind object auto-deduce the type. I've tried creating an object generator make_postbind(service, handle) but it was unable to deduce the types automatically.
Below I've written a test case. Compiles using: g++ -o postbind postbind.cpp -std=c++0x -lboost_system
I'd like to get the line:
std::function<void (int)> func = postbind<int>(strand, std::bind(foo, myfoo(), 'a', _1));
Down to:
std::function<void (int)> func = postbind(strand, std::bind(foo, myfoo(), 'a', _1));
But am unsure how to. In my code, I'm starting to get some really lengthy postbind template specialisations that are beginning to eat up my horizontal whitespace :)
#include <boost/asio.hpp>
#include <thread>
#include <iostream>
#include <functional>
#include <memory>
using namespace boost::asio;
using std::shared_ptr;
typedef shared_ptr<io_service> service_ptr;
typedef shared_ptr<io_service::work> work_ptr;
typedef shared_ptr<io_service::strand> strand_ptr;
typedef std::shared_ptr<io_service::work> work_ptr;
using std::placeholders::_1;
template<typename... Args>
class postbind
{
public:
typedef std::function<void (Args...)> function;
postbind(strand_ptr strand, function memfunc)
: strand_(strand), memfunc_(memfunc)
{
}
void operator()(Args... params)
{
strand_->post(std::bind(memfunc_, std::forward<Args>(params)...));
}
private:
strand_ptr strand_;
function memfunc_;
};
// --------------------------------------------
struct myfoo
{
char a;
int b;
};
void run(service_ptr service)
{
service->run();
}
void foo(myfoo foo, char a, int x)
{
std::cout << "this thread: " << std::this_thread::get_id() << "\n"
<< x << "\n";
}
int main()
{
service_ptr service(new io_service);
strand_ptr strand(new io_service::strand(*service));
work_ptr work(new io_service::work(*service));
std::thread t(std::bind(run, service));
std::cout << "main thread: " << std::this_thread::get_id() << "\n";
std::function<void (int)> func = postbind<int>(strand, std::bind(foo, myfoo(), 'a', _1));
func(99);
t.join();
}
Thanks!
You could move your template specializations into another class so that you do not have to place them on your calls to postbind. For instance, create an empty class who's purpose is to simply hold all the long drawn-out template arguments:
template<typename... Args>
struct post_bind_traits {};
Now somewhere else in your code (i.e., another file), you could setup all the versions of arguments you would need. For instance, in a header file you could do the following:
typedef post_bind_traits<int, int> pb_int_int;
typedef post_bind_traits<double, int> pb_double_int;
//... additional definitions
Then you can create a partial template specialization of your postbind class that looks like the following:
template<typename... Args>
class postbind<post_bind_traits<Args...>> //add this partial specialization
{
public:
typedef std::function<void (Args...)> function;
postbind(strand_ptr strand, function memfunc)
: strand_(strand), memfunc_(memfunc)
{
}
void operator()(Args... params)
{
strand_->post(std::bind(memfunc_, std::forward<Args...>(params)));
}
private:
strand_ptr strand_;
function memfunc_;
};
Now you can call postbind, provided you have access to the typedef definitions in the header files, like the following:
postbind<pb_int_int>::function func = postbind<pb_int_int>(/* arguments */);
Pack all the complicated typedefs in your header, and you'll have a much cleaner code-set in your main code-module files.
I think the answer is no way. This is because of the difference between std::function and the return value of std::bind.
The function signature of std::function must be specified while being declared.
The signature of functor returned by std::bind has actually a variadic template arguments, which won't be decided until its operator() is invoked. It means that the signature is not unique at declaring time, which is definitely before evaluating time.
Look at the expected invocation, std::function<void(...)> func = postbind(strand, std::bind(foo, myfoo(), 'a', _1);. Actually, the compiler only knows the bound arguments and some placeholders. After a while, its operator() is invoked, then the unbound arguments are going to replace the placeholders, and now compiler can check whether all arguments matches the function signature or not.
If above sentences are too recondite to understand, please let me show some code:
void foo(int) {}
foo(1); // Correct.
foo(1, 2); // Illegal, signature mismatched.
auto f = std::bind(foo, _1); // Here f has no idea about unbound args for foo.
f(1); // OK, 1 matches int.
f(1, 2); // OK too, although 2 is used.
f(1, 1, 1); // Same as before ones.
auto func = postbind(
strand, std::bind(foo, _1)); // If this is acceptable,
func(99); // this is a correct invocation then.
func(99, 98); // And this should also be happy for compiler. Ambiguity!
As a result, you have to specify the signature explicitly while binding.
But anyway, here's a code snippet which might be a substitute solution I guess:
template <typename... ArgTypes>
void do_post(strand_ptr strand, ArgTypes&&... args)
{
strand->post(std::bind(std::forward<ArgTypes>(args)...));
}
int main()
{
// some code
auto original_closure = std::bind(foo, myfoo(), 'a', _1);
auto final_closure = std::bind(
do_post<decltype(std::ref(original_closure)), int>, // signature deduced here
strand, std::ref(original_closure), _1); // std::ref used for inner std::bind
final_closure(99);
// others
}