In C++:
I have an object I'll call Foo.
Foo performs statistical operations on a supplied data set. The first step of the process involves a fitting function, and a functional parameter can be supplied so that the user can specify the type of model being used.
The problem is that I now have a situation where the function parameter needs to have access to data that does not exist in Foo but rather in the object that is using Foo, which I will call Bar.
So Bar calls Foo to have Foo operate on Bar's data. Bar has a specific function it wants to use as the functional parameter but this function requires information specific to Bar.
I don't want to pass Bar because if I code Foo up to receive Bar, then every time I have a new object that needs additional info passed to Foo, I will have to adjust the Foo class to accept that object.
I don't want to modify the functional parameter input in Foo because then I'll have to modify the functional parameter input for every new usage case as well.
I considered using a base class I'll call StandardFunc. Then, via virtual methods, Bar could create an object called ModifiedFunc that derives from StandardFunc. It could override the StandardFunc's function and also supply the additional info as class parameters. This doesn't work either because to avoid slicing I have to type-cast ModifiedFunc to StandardFunc. This means that inside Foo I have to change the type-cast line for every new object name.
Can someone please point me in the right direction for how I can allow users to pass either a functional parameter alongside arbitrary parameters the function requires without having to recode the Foo class for every different usage case? I'm really stuck on this.
EDIT: pseudo code example:
class Foo
{
void processHandler(function)
void process();
void process(function);
void theUsualFunction(vector); //the default function used by process
vector vec;
};
void Foo::process()
{
processHandler(theUsualFunction);
}
void Foo::process(function f)
{
processHandler(f)
}
void Foo::processHandler(function f)
{
f(vec)
//do other stuff to vec
}
void Foo::theUsualFunction(vector v)
{
//default vec processor
}
class Bar
{
int x;
int y;
vector vec;
void theModifiedFunction(vector);
void callFooToProcess();
};
void Bar::theModifiedFunction(vector v)
{
//process v, but in a way that requires x and y
}
void Bar::callFooToProcess()
{
Foo foo;
foo.setVector(vec);
process(theModifiedFunction);
}
So this code is kind of an example of what I want to achieve, but it doesn't work as written. The reason is because I have no way of getting Bar::x and Bar::y to the function Foo::processHandler(function) without modifying the arguments for Foo::processHandler, and I don't want to do that because then every new class like Bar and every new theModifiedFunction that requires different data will require me to rewrite the arguments for processHandler.
This doesn't work either because to avoid slicing I have to type-cast ModifiedFunc to StandardFunc.
Slicing only occurs if you pass the argument by value. You should pass it as a pointer, that's how polymorphism is supposed to work.
Also, you can keep passing the argument by value if you make your class a template:
template<class Func>
class Foo {
void doStuff(Func func) {
...
}
}
Keep in mind though, that in this case Func has to be known at compile-time.
Although there may be other ways of handling this situation, I would suggest considering to have Bar contain Foo. This is called a has-a relationship [wiki]. The advantage of this is that you can use Foo as-is without modifying anything within Foo, as well as Bar need not pass around its private data. Hope the following code snippet would help you to understand the concept.
public class Bar
{
private Foo myFoo;
private int myInfo;
void a()
{
myFoo.doStuff(myInfo);
}
}
Related
Is it possible to pass different objects as argument for 1 function, not making 3 functions
i.e
void someFunction(Object o) {
//working with object, all that objects have same fields to work with
// i.e. all objects have x, y fields and this function is working with it
}
Player pl;
Item itm;
Block bl;
someFunction(pl);
someFunction(itm);
someFunction(bl);
Maybe it can be done using templates or what?
I dont want to make 3 functions with same code for different objects
Yes, using templates:
template<class Type> void someFunction(const Type& o) {
//working with object, all that objects have same fields to work with
// i.e. all objects have x, y fields and this function is working with it
}
Note that you probably will prefer to pass o by const reference, not by value. I have done this here.
Yes, a template should work:
template <typename T>
void someFunction(T & o)
{
// use o.x, o.y, o.z
}
You can pass by reference or const-reference, depending on whether you want to modify the original object or not.
Templates can be used as an alias for a class of types. The following will allow any type to pass through the parameters of f.
template <typename T> void f(T & t) {
// ...
}
A template should work, but without taking SFINAE into account, you cannot assure that all the given objects have some fields.
Another solution could be inheritance here some sample code:
struct Foo
{
int x;
int y;
};
struct Bar: public Foo
{
int another_x;
};
struct Baz: public Foo
{
int another_y;
};
void someFunction(const Foo &foo)
{
std::cout << foo.x << '\n';
std::cout << foo.y << '\n';
};
With this approach, you can assure that all the given objects have the required members.
You can do this with templates or polymorphism (probably a parent interface with virtual methods to get and set relevant fields).
Templates will work and probably be well optimized, but will not allow new objects to be passed in later, regardless of whether they have the same fields. You will be able to compile new code and new objects to use the template functions, but existing calls will be stuck with a single type.
Using a parent interface and virtual methods, then making your function call those methods (presumably getters and setters) to handle the field manipulation will provide more freedom later, at the expense of slightly higher runtime and having to inherit from that interface (it will, however, allow new objects to be passed to the function at any time, so long as they implement the interface).
I have a framework function which expects an object and a member function pointer (callback), like this:
do_some_work(Object* optr, void (Object::*fptr)()); // will call (optr->*fptr)()
How can I pass a lambda expression to it? Want to do somethink like this:
class MyObject : public Object
{
void mystuff()
{
do_some_work(this, [](){ /* this lambda I want to pass */ });
}
};
The meaning of it all is to not clutter the interface of MyObject class with callbacks.
UPD
I can improve do_some_work in no way because I don't control framework and because actually it isn't one function, there're hundreds of them. Whole framework is based on callbacks of that type. Common usage example without lambdas:
typedef void (Object::*Callback)();
class MyObject : public Object
{
void mystuff()
{
do_some_work(this, (Callback)(MyClass::do_work));
}
void do_work()
{
// here the work is done
}
};
SOLUTION Here's my solution based on Marcelo's answer:
class CallbackWrapper : public Object
{
fptr fptr_;
public:
CallbackWrapper(void (*fptr)()) : fptr_(fptr) { }
void execute()
{
*fptr_();
}
};
class MyObject : public Object
{
void mystuff()
{
CallbackWrapper* do_work = new CallbackWrapper([]()
{
/* this lambda is passed */
});
do_some_work(do_work, (Callback)(CallbackWrapper::execute));
}
};
Since we create the CallbackWrapper we can control it's lifetime for the cases where the callback is used asynchonously. Thanks to all.
This is impossible. The construct (optr->*fptr)() requires that fptr be a pointer-to-member. If do_some_work is under your control, change it to take something that's compatible with a lambda function, such as std::function<void()> or a parameterised type. If it's a legacy framework that isn't under your control, you may be able to wrap it, if it's a function template, e.g.:
template <typename Object>
do_some_work(Object* optr, void (Object::*fptr)());
Then, you can implement a wrapper template:
template <typename F>
void do_some_work(F f) {
struct S {
F f;
S(F f) : f(f) { }
void call() { f(); delete this; }
};
S* lamf = new S(f);
do_some_work(lamf, &S::call);
}
class MyObject // You probably don't need this class anymore.
{
void mystuff()
{
do_some_work([](){ /* Do your thing... */ });
}
};
Edit: If do_some_work completes asynchronously, you must allocate lamf on the heap. I've amended the above code accordingly, just to be on the safe side. Thanks to #David Rodriguez for pointing this out.
There are deeper problems with the approach that you are trying to take than the syntactical mismatch. As DeadMG suggests, the best solution is to improve the interface of do_some_work to take a functor of some sort (std::function<void()> in C++11 or with boost, or even a generic F on which operator() is called.
The solution provided by Marcelo solves the syntactical mismatch, but because the library takes the first element by pointer, it is the responsibility of the caller to ensure that the object will be alive when the callback is executed. Assuming that the callback is asynchronous, the problem with his solution (and other similar alternatives) is that the object can potentially be destroyed before the callback is executed, causing undefined behavior.
I would suggest that you use some form of plimp idiom, where the goal in this case would be to hide the need for callbacks (because the rest of the implementation might not need to be hidden you could use just another class to handle the callbacks but store it by value, if you don't want do have to dynamically allocate more memory):
class MyClass;
class MyClassCallbacks {
MyClass* ptr;
public:
MyClassCallbacks( MyClass* ptr ) : ptr(ptr) {}
// callbacks that execute code on `ptr`
void callback1() {
// do some operations
// update *ptr
}
};
class MyClass {
MyClassCallbacks callbackHandler;
public:
void mystuff() {
do_some_work( &callbackHandler, &MyClassHandler::callback1 );
}
};
In this design, the two classes are separated but represent a unique single entity, so it is fine to add a friend declaration and let MyClassCallbacks access the internal data in MyClass (both of them are one single entity, divided only to provide a cleaner interface, but coupling is already high, so adding the extra coupling requiered by friend is no problem).
Because there is a 1-1 relationship between MyClass and MyClassCallbacks instances, their lifetimes are bound and there would be no lifetime issues, except during destruction. During destruction you must ensure that there is no callback registered that can kick in while the MyClass object is being destroyed.
Since you are at it, you might want to walk the extra mile and do a proper pimpl: move all of the data and implementation into a different type that is held by pointer, and offer a MyClass that stores a pointer and offers just the public functions, implemented as forwarders to the pimpl object. This could be somehow tricky as you are using inheritance, and the pimpl idiom is a bit cumbersome to implement on type hierarchies (if you need to extend MyClass, deriving from Object could be done in the pimpl object, rather than the interface type).
I don't think you can do that. Your do_some_work() is declared to accept pointer to methods of class Object, so such should be provided. Otherwise optr->*fptr is invalid since the lambda is not member of Object. Probably you should try using std::function and adding the needed members of Object in its closure.
You must use std::function<void()>. Both function and member function pointers are highly unsuited to being callbacks.
I am creating a bunch of C structs so i can encapsulate data to be passed over a dll c interface. The structs have many members, and I want them to have defaults, so that they can be created with only a few members specified.
As I understand it, the structs need to remain c-style, so can't contain constructors. Whats the best way to create them? I was thinking a factory?
struct Foo {
static Foo make_default ();
};
A factory is overkill. You use it when you want to create instances of a given interface, but the runtime type of the implementation isn't statically known at the site of creation.
The C-Structs can still have member functions. Problems will, however, arise if you start using virtual functions as this necessitates a virtual table somewhere in the struct's memory. Normal member functions (such as a constructor) don't actually add any size to the struct. You can then pass the struct to the DLL with no problems.
I would use a constructor class:
struct Foo { ... };
class MakeFoo
{
Foo x;
public:
MakeFoo(<Required-Members>)
{
<Initalize Required Members in x>
<Initalize Members with default values in x>
}
MakeFoo& optionalMember1(T v)
{
x.optionalMember1 = v;
}
// .. for the rest option members;
operator Foo() const
{
return x;
}
};
This allows to arbitrary set members of the struct in expression:
processFoo(MakeFoo(1,2,3).optionalMember3(5));
I have an easy idea, here is how:
Make the structure, just like you normally would, and create a simple function that initializes it:
struct Foo{...};
void Default(Foo &obj) {
// ... do the initialization here
}
If you have multiple structures, you are allowed in C++ to overload the function, so you can have many functions called 'default', each initializing its own type, for example:
struct Foo { //... };
struct Bar { //... };
void Default(Foo &obj) {...}
void Default(Bar &obj) {...}
The C++ compiler will know when to call the first or the second overload based on the parameter. The & makes obj a reference to whatever parameter you give it, so any changes made to obj will be reflected to the variable you put as parameter.
Edit:
I also have an idea for how to specify some parameters, you can do it by using default parameters. This is how it works:
For example you the following function; you can specify default values for parameters like this:
void Default (Foo &obj, int number_of_something = 0, int some_other_param = 10)
{ ... }
I'm having a class with 2 pure virtual methods and another class which needs to use an object of this class. I want to allow the user of this class to specify which derivation of the abstract class should be used inside of it.
I'm struggling to figure out what the right way is.
struct abstract {
virtual int fst_func() = 0;
virtual void sec_func(int) = 0;
};
// store an instance of "abstract".
class user_of_abstract
{
private:
abstract* m_abstract;
public:
// Pass a pointer to an "abstract" object. The caller takes care of the memory resource.
user_of_abstract_base(abstract* a) : m_abstract(a) { }
// Pase any type, which needs to be derived from "abstract" and create a copy. Free memory in destructor.
template<class abstract_type>
user_of_abstract_base(abstract_type const& a) : m_abstract(new abstract_type(a)) { }
// use the stored member to call fst_func.
int use_fst_func() {
return this->m_abstract->fst_func();
}
// use the stored member to call sec_func.
void use_sec_func(int x) {
this->m_abstract->sec_func(x);
}
};
// use boost::shared_ptr
class user_of_abstract
{
private:
boost::shared_ptr<abstract> m_abstract;
public:
// Pass a pointer to an "abstract" object. The caller takes care of the memory resource.
user_of_abstract_base(boost::shared_ptr<abstract> a) : m_abstract(a) { }
// use the stored member to call fst_func.
int use_fst_func() {
return this->m_abstract->fst_func();
}
// use the stored member to call sec_func.
void use_sec_func(int x) {
this->m_abstract->sec_func(x);
}
};
// pass a pointer of an "abstract" object wherever needed.
struct user_of_abstract
{
// use the passed pointer to an "abstract" object to call fst_func.
int use_fst_func(abstract* a) {
return a->fst_func();
}
// use the passed pointer to an "abstract" object to call sec_func.
void use_sec_func(abstract* a, int x) {
a->sec_func(x);
}
};
It's important to note that parameter "x" from sec_func() needs to be a value returned by fst_func() on the same "abstract" instance.
EDIT:
Added another approach using boost::shared_ptr which should take the most advantages.
I would say that passing the abstract object into the constructor of your user is the proper approach as the methods of the user depend being called on the same abstract object. I would even go further and make the x parameter an internal state of your user as you have said it's important that this value is the one returned from a call from the first function.
Update: If you are worried about the lifetimes then you could make use of the various smart pointer options available in for example boost. Those should cover most usage scenarios.
Since you say the second function should use the output of the first. I guess first approach will decrease chance of mistakes. You can even modify it to the following:
int use_fst_func() {
return x=this->m_abstract->fst_func();
}
void use_sec_func() {
this->m_abstract->sec_func(x);
}
protected:
int x;
You're putting yourself in a sea of maintenance trouble.
In your first example...
there's really no need for the template constructor. It's speced as
// Parse any type, which needs to be derived from "abstract" and create a copy.
The user can already do that by creating the instance himself and pass it to the first constructor.
Also, with this:
// Free memory in destructor.
You explicitly say that you have no idea how this class should be used. As your first example is written, you need to decide: use an instance created from the outside or use an instance created on the inside. It's confusing to see an interface with one ctor taking a pointer and another ctor taking a reference, both essentially to the same type.
In my eyes, the only acceptable way of using an instance created from the outside that will not be memory-managed or an instance created from the inside that will be memory-managed, is when there's a default ctor that can initialize the internal pointer to a sensible value (but that doesn't seem to be the case here, since you want to copy another instance):
template <typename T>
class user_of_abstract
{
bool m_owner_;
abstract* m_abstract;
public:
user_of_abstract_base(abstract* a = NULL)
: m_owner(a == NULL)
, m_abstract(m_owner ? new T(): a)
{
}
~user_of_abstract_base()
{
if (m_owner)
{
delete m_abstract;
}
}
}
Your second example...
is superior to the first, since you don't explicitly mix memory management with memory reference. You let shared_ptr do it implicitly. Very good, that's what it's for.
However, since you have a requirement that use_sec_func must take the output of use_fst_func as input, you stay a long way from the safe shore of the sea of maintenance problems.
For instance, what happens if use_fst_func on an instance throws an exception and use_sec_func is later called on that same instance?
How do you expect that the important information "Always call A before B. And only once. And pass the A result to B." should propagate to users of the class 2 years from now?
Why can't use_sec_func just call use_fst_func?
As for your third example...
can you give 1 single scenario when you'd want to use this instead of just calling the instance functions directly?
In my C++ code I have a class Foo with many methods taking a Bar type variable as an argument:
class Foo {
public:
void do_this(Bar b);
void do_that(Bar b);
/* ... */
};
Bar has a number of constructors that create a new object from many common types such as int, std::string, float, etc:
class Bar {
public:
Bar(int i);
Bar(float f);
Bar(std::string s);
/* ... */
};
I wrapped this with Boost::Python and I'm now able to call my Foo methods using Python literals directly, as they get implicitly converted to Bar objects.
f = Foo()
f.do_this(5)
f.do_that("hello")
Now, I would like to be able to use also other Python types, such as tuples, like this:
f.do_that((1,2,3))
But I don't want to touch the original Bar definition, and I don't want to pollute my C++ library with Boost::Python stuff. I want to write a wrapper function in my binding code, but I just can't understand if this is possible and what is the correct way for doing this.
In other words: can I register a factory function to be used as an automatic conversion in Python?
Subclass Bar near the wrapper code and give your subclass a ctor that takes a bp::object (or a more specific python type)
struct Bar_wrapper:Bar,bp::wrapper<Bar>
{
Bar_wrapper(bp::object arg)
{
//code to build a Bar_wrapper Here
}
}
Then export a Bar_wrapper to python instead of a Bar, and call it a Bar as the python name:
class<Bar_wrapper>("Bar")
...
.def(init<bp::object>())
...
Add a new constructor template <typename T> Bar(T)
in your header and implement as template <>
Bar::Bar(Tupple) {}
Create some type TupleCollector with overridden "operator ,(int)" so you can write
f.do_that((TuppleCollector(), 1, 2, 3))
at last create conversion between TupleCollector and expected target
You can make a static factory method and then expose it as one of the Python constructors for the class. Just make a converter that will take any Python object and you're free do do whatever your please.
using namespace boost::python;
Bar CreateBar(object obj)
{
// Do your thing here
return Bar;
}
// ..................
class_<Bar>("Bar")
// .....................
.def("__init__", make_constructor(&CreateBar))
//.............
;
You can register from-python converter which will construct Bar instance from arbitrary object. See here and an exmaple of my own (converts either (Vector3,Quaternion) tuple or 7*double-tuple to 3d transformation Se3) here.
Note that the logic has two steps, first you determine whether the object is convertible (convertible; in your case, you check that it is a sequence, and has the right number of elements), then the construct method is called, which actually returns the instance, allocated with the pointer passed as parameter.
The converter must then be registered in BOOST_PYTHON_MODULE. Since the converter registry is global, once registered, it will be subsequently used automatically everywhere. All function argument of type Bar or const Bar& should be handled just fine (nor sure about Bar& from the top of my head).
You can export function do_that which take boost::python::object param, check if param is a python tuple, extract data and pass it to object.