I use BOOST_PHOENIX_ADAPT_FUNCTION all the time in Spirit. I'd like to be able to adapt member functions for all of the same reason. However, I get compile errors if I do something like this:
struct A { int foo(int i) { return 5*i; }};
BOOST_PHOENIX_ADAPT_FUNCTION(int, AFoo, &A::foo, 2)
Is there an easy way to adapt a member function? Note that I can't just store a bind expression in an auto because I am on VC2008. How come it doesn't just work like in bind and function?
Thanks,
Mike
The BOOST_PHOENIX_ADAPT_FUNCTION(RETURN,LAZY_NAME,FUNC,N)is really simple. It just creates a functor with a templated operator() that returns RETURN and has N template parameters. In its body it simply invokes FUNC(PARAMETERS...). But &A::foo is not directly callable, and so your error occurs. You can use:
BOOST_PHOENIX_ADAPT_FUNCTION(int,AFoo,boost::mem_fn(&A::foo),2)
Running on Coliru
#include <iostream>
#include <boost/phoenix.hpp>
#include <boost/phoenix/function.hpp>
#include <boost/mem_fn.hpp>
struct A {
A(int f) : f_(f) {}
int foo(int i) {
return f_*i;
}
private:
int f_;
};
BOOST_PHOENIX_ADAPT_FUNCTION(int,AFoo,boost::mem_fn(&A::foo),2)
int main() {
using namespace boost::phoenix;
using namespace boost::phoenix::arg_names;
A instance(5);
std::cout << AFoo(arg1,arg2)(&instance, 2) << std::endl;
}
Starting with the simplest:
How come it doesn't just work like in bind and function?
Because the macro is designed for functions, not member functions. Pointer-to-member-functions are very different from function pointers, so that's the end of the road.
In your example, A::foo doesn't actually need to be an instance method (non-static member function), so just add static (and an implicit parameter) and be done:
struct A {
static int foo(int i) {
return 5*i;
}
};
BOOST_PHOENIX_ADAPT_FUNCTION(int, AFoo, A::foo, 1)
Let's assume, though, that you did want to have the non-static member function. For this reason, let's add a little state to the A type:
struct A {
A(int f) : f_(f) {}
int foo(int i) { return f_*i; }
private:
int f_;
};
Phoenix provides the following approaches to create lazy actors calling member functions:
use the ->* operator. This leads to slightly obscure syntax:
A instance(9);
int direct = (arg1->*&A::foo)(arg2)
(&instance, 7); // direct == 63
alternatively, you can use a bind expression (note: boost::phoenix::bind here!), which might just be what you were looking for:
int with_bind = bind(&A::foo, arg1, arg2)
(&instance, 7);
Now, of course, you might be looking to assign the lazy functor to a variable. In that respect, I can only recommend BOOST_AUTO:
BOOST_AUTO(afoo, (arg1->*&A::foo)(arg2));
return afoo(&instance, 2);
Which works like a charm.
Full C++03 Sample
See it Live on Coliru
struct A {
A(int f) : f_(f) {}
int foo(int i) {
return f_*i;
}
private:
int f_;
};
#include <boost/phoenix.hpp>
#include <boost/phoenix/function.hpp>
#include <cassert>
int main() {
using namespace boost::phoenix;
using namespace boost::phoenix::arg_names;
A instance(9);
int direct = (arg1->*&A::foo)(arg2)
(&instance, 7);
int with_bind = bind(&A::foo, arg1, arg2)
(&instance, 7);
assert(direct == with_bind);
BOOST_AUTO(afoo, (arg1->*&A::foo)(arg2));
return afoo(&instance, 2);
}
Related
I have a namespace, N0, that has sub-namespaces including N1. The calling code only knows about the outer namespace. I'd like to write a function in the outer namespace that returns a std::unique_ptr<N1::T> where that result is consumed elsewhere in N0. However, the caller shouldn't know about N1. What I'd like to do is something like:
// N0.h
namespace N0 {
typename T; // This isn't real C++.
std::unique_ptr<T> foo();
void bar(std::unique_ptr<T>&&);
}
// N0.cpp
#include "N1.h" // Get N1::T
namespace N0 {
typedef N1::T T;
...
}
That is, I'd like to expose a type that the caller can't see but internally I'd like to actually use a type in a different namespace. This way elsewhere someone could just forward-declare namespace N0 { class T; } without having to know that T is actually in N1.
I could move T itself into N0, but it really belongs in N1.
I could wrap T with a dummy class in N0, but that's ugly, and the pointer should basically do that.
I could probably make a class N0::T that subclasses N1::T, but that seems icky too.
Is there no way for N0 to forward declare that "I have a type and you don't need to know what it is" and have that type actually be in a different namespace? Put another way: Why is class C; class C{}; legal but class C; typedef int C; is illegal? (Likewise class C; using C = int; or typedef C; typedef int C;.) They seem fundamentally the same to me and I can't think of a clever template trick to get around it. The only difference I can think of is that the typedef version wouldn't be subject to Koenig lookup.
I mean you could do this:
// N0.h
namespace N0 {
std::unique_ptr<T> foo();
void bar(std::unique_ptr<T>&&);
}
// N0.cpp
namespace N0 {
typedef N1::T t;
}
#include "N0.h"
namespace N0 {
// whatever...
}
In the situation you have described, the foo should be implemented as a template function:
namespace N0 {
template <typename T>
std::unique_ptr<T> foo(){...};
template <typename T>
void bar(std::unique_ptr<T>&&){...};
}
And you should using a wrap/overload function to do the final trick:
namespace N0 {
std::unique_ptr<N1::T> foo() { return foo<N1::T>(); }
//for bar there is no need to wrap, cause the T could be resolved by parameters.
}
Here's the best I've come up with, which seems to work. I still feel like there should be a way to not use "tricks" to make N1::T fully hidden from callers:
// N0.h
#pragma once
#include <memory>
namespace N0 {
struct OpaqueObject { virtual ~OpaqueObject() {} };
std::unique_ptr<OpaqueObject> foo();
void bar(std::unique_ptr<OpaqueObject>&&);
}
//N0.cpp
#include "N1.h"
namespace N0 {
std::unique_ptr<OpaqueObject> foo() { return std::unique_ptr<N1::T>(new N1::T()); }
void bar(std::unique_ptr<OpaqueObject> &&) {}
}
// N1.h
#pragma once
#include "N0.h"
namespace N1 {
class T : public N0::OpaqueObject {};
}
// test.cpp
#include "N0.h"
int main() {
auto x = N0::foo();
N0::bar(std::move(x));
}
I have a slightly convoluted use case of passing a member function pointer to an outside function which is then called again by a member function (Don't ask!). I'm learning about std::function and std::mem_fn but I can't seem to be able to convert my old school function pointer
void (T::*func)(int) to a std::function<void (T::*)(int) func>
in the code below, I'd like to be able to pass a std::function to memFuncTaker in the call from anotherMember
#include "class2.hpp"
#include <iostream>
class outer{
public:
void aMember(int a){
std::cout << a <<std::endl;
}
void anotherMember(double){
memFuncTaker(this, &outer::aMember);
}
};
template<class T>
void memFuncTaker(T* obj , void (T::*func)(int) ){
(obj->*func)(7);
}
When you bind std::function to a non-static member function pointer, it "reveals" the hidden this parameter, making it the first explicit parameter of the resultant functor. So in your case for outer::aMember you'd use std::function<void(outer *, int)> and end up with a two-parameter functor
#include <functional>
#include <iostream>
template<class T>
void memFuncTaker(T *obj , std::function<void(T *, int)> func){
func(obj, 7);
}
class outer{
public:
void aMember(int a){
std::cout << a <<std::endl;
}
void anotherMember(double){
memFuncTaker(this, std::function<void(outer *, int)>{&outer::aMember});
}
};
int main() {
outer o;
o.anotherMember(0);
}
http://coliru.stacked-crooked.com/a/5e9d2486c4c45138
Of course, if you prefer, you can bind the first argument of that functor (by using std::bind or lambda) and thus "hide" it again
#include <functional>
#include <iostream>
using namespace std::placeholders;
void memFuncTaker(std::function<void(int)> func){
func(7);
}
class outer{
public:
void aMember(int a){
std::cout << a <<std::endl;
}
void anotherMember(double){
memFuncTaker(std::function<void(int)>(std::bind(&outer::aMember, this, _1)));
}
};
int main() {
outer o;
o.anotherMember(0);
}
Note that in this version memFuncTaker no longer has to be a template (which happens to be one of the primary purposes of std::function - employ type erasure techniques to "de-templatize" the code).
I have a bit of trouble understanding a std::bind call.
In the following example:
#include <functional>
#include <iostream>
#include <memory>
class Notifier
{
public:
Notifier(std::function<void(Notifier&)> on_notify)
:on_notify_(on_notify)
{ }
void notify()
{
if (on_notify_)
on_notify_(*this);
}
std::function<void(Notifier&)> on_notify_;
};
struct Manager
{
Manager()
{
n_ = std::make_unique<Notifier>(std::bind(&Manager::trigger, this));
}
void trigger()
{
std::cout << "notified" << std::endl;
}
std::unique_ptr<Notifier> n_;
};
int main()
{
Manager s;
s.n_->notify();
}
I don't understand how on_notify_(*this); calls back the functor with a Notifier& parameter, but the functor created by bind doesn't specify it.
The calls result correctly to the void notify() method, but I don't understand what exactly will be the functor created by bind to result in this.
If I were to write a lambda instead, I would need to specify the parameter, otherwise it would compile.
What kind of operation does bind here behind my back? :-)
std::bind basically ignores the invalid given argument according to this.
If some of the arguments that are supplied in the call to g() are not matched by any placeholders stored in g, the unused arguments are evaluated and discarded.
It might surprise you that when even more absurd arguments are provided, the binded functor can still successfully reach Manager::trigger() as follows:
#include <functional>
#include <iostream>
#include <memory>
// Some classes that have nothing to do with on_notify_
class AAA {};
class BBB {};
class Notifier
{
public:
Notifier(std::function<void(AAA&, BBB&)> on_notify)
:on_notify_(on_notify)
{ }
void notify()
{
if (on_notify_)
{
// Arguments not matching.
AAA a{};
BBB b{};
// Invoke with them.
on_notify_(a, b);
}
}
std::function<void(AAA&, BBB&)> on_notify_;
};
struct Manager
{
Manager()
{
n_ = std::make_unique<Notifier>(std::bind(&Manager::trigger, this));
}
void trigger()
{
std::cout << "it's also notified!" << std::endl;
}
std::unique_ptr<Notifier> n_;
};
int main()
{
Manager s;
s.n_->notify();
}
Live demo is here.
#include <iostream>
using namespace std;
class B
{
public:
int getMsg(int i)
{
return i + 1;
}
};
class A
{
B b;
public:
void run()
{
taunt(b.getMsg);
}
void taunt(int (*msg)(int))
{
cout << (*msg)(1) << endl;
}
};
int main()
{
A a;
a.run();
}
The above code has a class B inside a class A, and class A has a method taunt that takes a function as an argument. class B's getMsg is passed into taunt...The above code generated the following error message: "error: no matching function for call to 'A::taunt()'"
What's causing the error message in the above code? Am I missing something?
Update:
#include <iostream>
using namespace std;
class B
{
public:
int getMsg(int i)
{
return i + 1;
}
};
class A
{
B b;
public:
void run()
{
taunt(b.getMsg);
}
void taunt(int (B::*msg)(int))
{
cout << (*msg)(1) << endl;
}
};
int main()
{
A a;
a.run();
}
t.cpp: In member function 'void A::run()':
Line 19: error: no matching function for call to 'A::taunt()'
compilation terminated due to -Wfatal-errors.
I'm still getting the same error after changing (*msg)(int) to (B::*msg)(int)
b.getMsg is not the correct way to form a pointer to member, you need &B::getMsg.
(*msg)(1) is not the correct way to call a function through a pointer to member you need to specify an object to call the function on, e.g. (using a temporary) (B().*msg)(1).
The right way to do such things in OOP is to use interfaces so all you need to do is to define an interface and implement it in B class after that pass the pointer of instance which implements this interface to your method in class A.
class IB{
public:
virtual void doSomething()=0;
};
class B: public IB{
public:
virtual void doSomething(){...}
};
class A{
public:
void doSomethingWithB(IB* b){b->doSomething();}
};
This works in VS 2010. The output is the same on all lines:
#include <iostream>
#include <memory>
#include <functional>
using namespace std;
using namespace std::placeholders;
class A
{
public:
int foo(int a, float b)
{
return int(a*b);
}
};
int main(int argc, char* argv[])
{
A temp;
int x = 5;
float y = 3.5;
auto a = std::mem_fn(&A::foo);
cout << a(&temp, x, y) << endl;
auto b = std::bind(a, &temp, x, y);
cout << b() << endl;
auto c = std::bind(std::mem_fn(&A::foo), &temp, _1, y);
cout << c(5) << endl;
}
Basically, you use std::mem_fn to get your callable object for the member function, and then std::bind if you want to bind additional parameters, including the object pointer itself. I'm pretty sure there's a way to use std::ref to encapsulate a reference to the object too if you'd prefer that. I also included the _1 forwarding marker just for another way to specify some parameters in the bind, but not others. You could even specify everything BUT the class instance if you wanted the same parameters to everything but have it work on different objects. Up to you.
If you'd rather use boost::bind it recognizes member functions and you can just put it all on one line a bit to be a bit shorter: auto e = boost::bind(&A::foo, &temp, x, y) but obviously it's not much more to use completely std C++11 calls either.
I have the following problem. I have a function from an external library (which cannot be modified) like this:
void externalFunction(int n, void udf(double*) );
I would like to pass as the udf function above a function member of an existing class. Please look at the following code:
// External function (tipically from an external library)
void externalFunction(int n, void udf(double*) )
{
// do something
}
// User Defined Function (UDF)
void myUDF(double* a)
{
// do something
}
// Class containing the User Defined Function (UDF)
class myClass
{
public:
void classUDF(double* a)
{
// do something...
};
};
int main()
{
int n=1;
// The UDF to be supplied is myUDF
externalFunction(n, myUDF);
// The UDF is the classUDF member function of a myClass object
myClass myClassObj;
externalFunction(n, myClassObj.classUDF); // ERROR!!
}
I cannot declare the classUDF member function as a static function, so the last line of the code above results in a compilation error!
This is impossible to do - in c++, you must use either a free function, or a static member function, or (in c++11) a lambda without capture to get a function pointer.
GCC allows you to create nested function which could do what you want, but only in C. It uses so-called trampolines to do that (basically small pieces of dynamically generated code). It would be possible to use this feature, but only if you split some of the code calling externalFunction to a separate C module.
Another possibility would be generating code at runtime eg. using libjit.
So if you're fine with non-reenrant function, create a global/static variable which will point to this and use it in your static function.
class myClass
{
public:
static myClass* callback_this;
static void classUDF(double* a)
{
callback_this.realUDF(a);
};
};
Its really horrible code, but I'm afraid you're out of luck with such a bad design as your externalFunction.
You can use Boost bind or TR1 bind (on recent compilers);;
externalFunction(n, boost::bind(&myClass::classUDF, boost::ref(myClassObj)));
Unfortunately, I lived in a pipe dream for the last 10 minutes. The only way forward is to call the target using some kind of a static wrapper function. The other answers have various neat (compiler-specific) tidbits on that, but here's the main trick:
void externalFunction(int n, void (*udf)(double*) )
{ double x; udf(&x); }
myClass myClassObj;
void wrapper(double* d) { myClassObj.classUDF(d); }
int main()
{
externalFunction(1, &wrapper);
}
std::function<>
Store a bound function in a variable like this:
std::function<void(double*)> stored = std::bind(&myClass::classUDF, boost::ref(myClassObj))
(assuming C++0x support in compiler now. I'm sure Boost has a boost::function<> somewhere)
Vanilla C++ pointers-to-member-function
Without magic like that, you'd need pointer-to-memberfunction syntax:
See also live on http://ideone.com/Ld7It
Edit to clarify to the commenters, obviously this only works iff you have control over the definition of externalFunction. This is in direct response to the /broken/ snippet int the OP.
struct myClass
{
void classUDF(double* a) { };
};
void externalFunction(int n, void (myClass::*udf)(double*) )
{
myClass myClassObj;
double x;
(myClassObj.*udf)(&x);
}
int main()
{
externalFunction(1, &myClass::classUDF);
}
C++98 idiomatic solution
// mem_fun_ref example
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>
int main ()
{
std::vector<std::string> numbers;
// populate vector:
numbers.push_back("one");
numbers.push_back("two");
numbers.push_back("three");
numbers.push_back("four");
numbers.push_back("five");
std::vector <int> lengths (numbers.size());
std::transform (numbers.begin(), numbers.end(), lengths.begin(),
std::mem_fun_ref(&std::string::length));
for (int i=0; i<5; i++) {
std::cout << numbers[i] << " has " << lengths[i] << " letters.\n";
}
return 0;
}
Here is how I do this, when MyClass is a singleton:
void externalFunction(int n, void udf(double) );
class MyClass
{
public:
static MyClass* m_this;
MyClass(){ m_this = this; }
static void mycallback(double* x){ m_this->myrealcallback(x); }
void myrealcallback(double* x);
}
int main()
{
MyClass myClass;
externalFunction(0, MyClass::mycallback);
}