Template cast to super class - c++

I want to be able to pass functions with an object of class I as parameter, where I inherits from D, to FD constructor::
class D {}; class I: public D {};
FD(std::function<void(D*)> f): _f(f) {}
void test(I*) { std::cout << "Success" << std::endl; }
FD fd(test); fd.call();
As I have been researching I should implement a type conversion, but I do not know a clean way and did not find answers addressing type conversions appliable to my case.
Here is the full code:
#include <functional>
#include <iostream>
class D {}; class I: public D {};
class FD {
protected:
std::function<void(D*)> _f;
public:
explicit FD(std::function<void(D*)> f): _f(f) {}
void call() { _f(0); }
};
void test(I*) { std::cout << "Success" << std::endl; }
int main () {
FD fd(test); fd.call();
}
I get:
test.cpp: In function ‘int main()’:
test.cpp:17:13: error: no matching function for call to ‘FD::FD(void (&)(I*))’
FD fd(test); fd.call();
^
test.cpp:10:14: note: candidate: FD::FD(std::function<void(D*)>)
explicit FD(std::function<void(D*)> f): _f(f) {}
^~
test.cpp:10:14: note: no known conversion for argument 1 from ‘void(I*)’ to ‘std::function<void(D*)>’
I have also tried using int and double:
#include <functional>
#include <iostream>
class FD {
protected:
std::function<void(double)> _f;
public:
explicit FD(std::function<void(double)> f): _f(f) {}
void call() { _f(0); }
};
void test(int v) { std::cout << "Success" << std::endl; }
int main () {
FD fd(test); fd.call();
}
With output:
Success

It's possible to explain the reason for the compilation error in excruciating technical detail, and why you cannot do what you want to do, in C++, but perhaps this fundamental reason will be clear to you if you consider a very simple thought experiment:
std::function<void(D*)> f;
You surely understand that this callable object can be called using a pointer to any subclass of D. You might have some other class called J that also inherits from D, and so this is perfectly acceptable:
class J : public D {};
J j;
f(&j);
But you are attempting to do here is construct your std::function using a pointer to a function that takes only I * as a parameter:
void test(I*)
If what you were attempting to do was possible, then this will mean that this test() function can be called, via the std::function<void (D*)> object, using a pointer to J, instead of I. Fail. This is, of course, is not allowed in C++. If the only relationship between two classes is that they all have the same parent class, you simply cannot convert a pointer to one of them to a pointer to the other one. C++ does not work this way.
And the reason why your 2nd example, with ints and doubles work, is because ints and doubles can be converted to each other. The same is not true with pointers to two random classes. A pointer to a class can be converted to a pointer to a different class only in certain, well-defined cases. What you want is not allowed in C++.
The only thing that can happen here is the test() function taking a D * as a parameter, crossing its fingers and attempting to dynamic_cast it to an I * (assuming that D meets the requirements for a dynamic-castable class). And then you will have to decide what happens when this conversion fails.

Of course, you can do the cast like this: FD fd(reinterpret_cast<void(*)(D*)>(test)); but this is UB.
The error is clear - you can't implicitly cast D* to I*. This violates polymorphism.
Are you sure you are not mixing up I and D?
UPD:
I assume downvoting this post means it is not clear. I will try to explain:
Imagine the following:
class D
{
public:
void (*ok)() = +[] { std::cout << "OK"; };
};
class I: public D
{
public:
void (*not_ok)() = ok;
};
ok() can be accesed from D instance while not_ok() cannot. Now you want to call your function taking pointer to I. But that means your function can call not_ok() which is not valid for pointer to D:
void test(I* i)
{
i->ok();
i->not_ok();
}
With raw pointers you can try this:
class FD {
protected:
std::function<void(D*)> _f;
public:
explicit FD(void(*f)(I*)) : _f(reinterpret_cast<void(*)(D*)>(f))
{
}
void call() { _f(new I); }
};
It will print OKOK. But if you replacenew I with new D it will fail on not_ok() call
This is why C++ doesn't allow to implicitly cast pointers (while you still can implicitly cast int to double).
Even if you want to 'hack' your code, C++ has no global type conversion rules. Also, you can't get raw pointer from std::function, therefore, there is no way to do this.

Related

Pass member function pointer to parent class yields compiler error

I'd like to have child classes register callbacks to their parent class so that users of the parent class can call methods of the child with a known function signature.
typedef int(*Func)(int);
class A
{
public:
void registerFunc(Func f)
{}
};
class B : public A
{
public:
B()
{
A::registerFunc(&B::myF);
}
int myF(int x) {
// do stuff with member variables
return 3;
}
};
But I get this compiler error
main.cpp:18:23: error: cannot initialize a parameter of type 'Func' (aka 'int (*)(int)') with an rvalue of type 'int (B::*)(int)'
A::registerFunc(&B::myF);
^~~~~~~
main.cpp:8:28: note: passing argument to parameter 'f' here
void registerFunc(Func f)
Here's a Repl illustrating the error in a concise example.
https://replit.com/#Carpetfizz/RudeSmoothComments#main.cpp
The accepted answer in a related thread suggested to override a virtual function declared in A but my use case actually requires dynamic callback registrations.
You can try this.
typedef std::function<int (int)> Func;
class A
{
public:
void registerFunc(Func f)
{}
};
class B : public A
{
public:
B()
{
A::registerFunc(std::bind(&B::myF, *this, std::placeholders::_1));
}
int myF(int x) {
// do stuff with member variables
return 3;
}
};
If I understand the goal (and believe me, that's a sketchy 'if'), you want to specify some member of some A derivation to invoke from some A member as a dispatched 'callback' mechanic. If that is the case, then to answer your question in comment, yes, a function and bind can do this. It can even be semi-protected with a little help from sfinae:
Example
#include <iostream>
#include <type_traits>
#include <functional>
#include <memory>
struct A
{
virtual ~A() = default;
std::function<void(int)> callback = [](int){};
template<class Derived>
std::enable_if_t<std::is_base_of<A, Derived>::value>
registerCallback(void (Derived::*pfn)(int))
{
using namespace std::placeholders;
callback = std::bind(pfn, dynamic_cast<Derived*>(this), _1);
}
void fire(int arg)
{
callback(arg);
}
};
struct B : public A
{
void memberfn(int arg)
{
std::cout << __PRETTY_FUNCTION__ << ':' << arg << '\n';
}
};
struct Foo
{
void memberfn(int arg)
{
std::cout << __PRETTY_FUNCTION__ << ':' << arg << '\n';
}
};
int main()
{
std::unique_ptr<A> ptr = std::make_unique<B>();
ptr->registerCallback(&B::memberfn);
// ptr->registerCallback(&Foo::memberfn); // WILL NOT WORK
ptr->fire(42);
}
Output
void B::memberfn(int):42
The Parts
The first part is straight forward. We declare a member variable callback to be a std::function<void(int)> instance. This is where we'll eventually bind our callable object point. The default value is a lambda that does nothing.
The second part is... a little more complicated:
template<class Derived>
std::enable_if_t<std::is_base_of<A, Derived>::value>
registerCallback(void (Derived::*pfn)(int))
This declares registerCallback as an available member function that accepts a non-static member function pointer taking one int as an argument, but only if the class hosting that member function, or a derivative therein, is a derivation of A (or A itself). Some non-A derivative Foo with a member void foo(int) will not compile.
Next, the setup to the callback itself.
using namespace std::placeholders;
callback = std::bind(pfn, dymamic_cast<Derived*>(this), _1);
This just binds the pointer-to-member to this dynamic-cast to the derivation type (which had better work or we're in trouble, see final warning at the end of this diatribe), and sets the call-time placeholder. The _1 you see comes from the std::placeholders namespace, and is used to delay providing an argument to the callback until such time as we actually invoke it (where it will be required,and you'll see that later). See std::placehholders for more information.
Finally, the fire member, which does this:
void fire(int arg)
{
callback(arg);
}
This invokes the registered function object with the provided argument. Both the member function and this are already wired into the object. The argument arg is used to fill in the placeholder we mentioned earlier.
The test driver for this is straightforward:
int main()
{
std::unique_ptr<A> ptr = std::make_unique<B>();
ptr->registerCallback(&B::memberfn);
// ptr->registerCallback(&Foo::memberfn); // WILL NOT WORK
ptr->fire(42);
}
This creates a new B, hosting it in a dynamic A pointer (so you know there is no funny business going on). Even with that, because B derived from A the registerCallback sfinae filtering passes inspection and the callback is registered successfully. We then invoke the fire method, passing our int argument 42, which will be sent to the callback, etc.
Warning: With great power comes great responsibility
Even those there is protection from passing non-A derived member functions, there is absolutely none from the casting itself. It would be trivial to craft a basic A, pass a B member (which will work since A is its base), but there is no B actually present.
You can catch this at runtime via that dynamic_cast, which we're currently not error checking. For example:
registerCallback(void (Derived::*pfn)(int))
{
using namespace std::placeholders;
Derived *p = dynamic_cast<Derived*>(this);
if (p)
callback = std::bind(pfn, p, _1);
}
You can choose the road more risky. Personally, i'd detect the null case and throw an exception just to be safe(er)

C++ Calling functions with different signatures, depending on type

I'm wondering what is a good design pattern is for the following scenario. Three questions:
1) I have a templated "Container" class for subclasses of "Derived". I want to be able to store different kinds of template objects (of either type A or B, both subclasses of Derived) in a vector. How to do this?
2) I have a template-specific function "func" that operates on Containers and has a variable number of arguments, depending on whether the template type of Container is A or B. What's a good way to check template types at runtime to call the appropriate function?
3) Do templates even make sense for this use case?
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
struct Derived {};
struct A : Derived {
int x;
A(int x) : x(x) {}
};
struct B : Derived {
bool y;
B(bool y) : y(y) {}
};
template <typename T>
struct Container
{
T item;
Container(T i) : item(i) {}
};
// definition of a template function for type a, with specialization
void func(Container<A> c, int a, int b) {
cout << "update for A called" << endl;
}
void func(Container<B> c, bool x) {
cout << "update for B called" << endl;
}
int main(int argc, char const *argv[])
{
Container<A> * foo = new Container<A>(A(1));
Container<B> * bar = new Container<B>(B(true));
// test that func() works
func(*foo,1,2);
func(*bar,false);
vector< Container<Derived>* > vec;
// this does not work
vec.push_back(unique_ptr< Container<Derived *> >(foo));
vec.push_back(unique_ptr< Container<Derived *> >(bar));
for (Container<Derived>* d : vec) {
// how to call the proper func(d)?
}
return 0;
}
1) You can store pointers to A (type A *) or pointers to B (type B *) in a std::vector<Derived *>, because Derived is a base for both A and B. It is not possible to store a Container<A> and a Container<B> into the same vector, because there is no inheritance relationship between them. This is also (indirectly) the reason that converting foo and bar to unique_ptr<Container<Derived *> > is being rejected by your compiler.
2) Your func() is not a "template specific function". It is not even a templated function. It is a function that is overloaded, with one variant that accepts two arguments, and one variant that accepts three.
3) Given that your code is invalid, it is not possible to infer what your use case is. Given that you are trying to convert objects to unrelated types, my guess is that your use case does not make sense in C++, let alone using templates for it.
Also, don't use Java (or whatever other language you are thinking in) techniques in C++, because they do not work the same way. Specifically;
Container<A> * foo = new Container<A>(A(1));
Container<B> * bar = new Container<B>(B(true));
func(*foo,1,2);
func(*bar,false);
is unnecessary. It is used in Java for various reasons that are invalid in C++, even if the code compiles. Instead, do this;
Container<A> foo A(1);
Container<B> bar B(true);
func(foo,1,2);
func(bar,false);
This is valid and safe C++ (and will not work in Java, but that's another story).

Function pointer in class A to member function from class B

I'm searching a solution for this for a few days now. Didn't find any question related enough to answer regrettably so here is my question.
Consider the next code:
// dummy class A
class A {
public:
void aFunction() { // <- this is the function I want to point at
cout << "aFunction() is called\n";
}
};
class B {
public:
template <class Class> // get a function pointer
void setFunction( void (Class::*func)() ) {
p_func = func;
}
void (*p_func)(); // the function pointer
}
int main() {
B obj;
objb.setFunction(&A::aFunction);
return 0;
}
I have a compilation error in setFunction() on p_func = func;:
cannot convert from 'void (__thiscall A::* )(void)' to 'void (__cdecl *)(void)'
And I don't seem to be able to get rid of it in any way. I know it has something to do with those invisible this pointers (__thiscall and __cdecl), but I don't know how to handle these. I tried making the member variable p_func a class template too (void (Class::*p_func)()) so it would have the same structure, but it that seems to be illegal to have 2 class templates in one class (why?), thus isn't the correct solution. This time the compiler complains about:
multiple template parameter lists are not allowed
This method (without the template) works perfectly on global functions (which is the workaround I currently use) and I saw the use of it in a library (sfgui), so it should be perfectly possible.
To have some context over why I'd want this: I'm trying to create a button. This button should be able to call whatever function I'd like. For now, I'd like it to call the start() function of an animation class I'm making.
p.s.: I know this example is useless since I can't run p_func: the function isn't static. I still need to add an object pointer (setFunction( void (Class::*func)(), Class* )), but that does not seem to be a problem. And I know about typedef to make a function pointer more readable, but not with a class template.
EDIT
After some more research I think the answer I need not the answer to this question, but rather another one. For once, I noticed that multiple template <class Class> is in fact allowed. However, it is not allowed on member variables since the compiler can't possibly know which class he'll need to use which probably is the reason for the error
multiple template parameter lists are not allowed
which is an odd description. Thanks anyway for the help, you did gave me a better insight.
You cannot convert a pointer-to-member Class::*func to a normal function pointer. They are of different types.
You should turn this:
void (*p_func)(); // the function pointer
into this:
void (class::*p_func)(); // the function pointer
You could also use a std::function<void()> and use boost::bind to bind it.
std::function<void()> fun = boost::bind(class::member_fun, args);
EDIT
What about making your B class a template so you can do this:
#include<iostream>
class A {
public:
void aFunction() { // <- this is the function I want to point at
std::cout << "aFunction() is called\n";
}
};
template<class T>
class B {
public:
void setFunction( void (T::*func)() ) {
p_func = func;
}
void (T::*p_func)(); // the function pointer
void callfunc()
{
(t.*p_func)(); //call pointer to member
}
private:
T t;
};
int main() {
B<A> obj;
obj.setFunction(&A::aFunction);
return 0;
}
Live Example
I found the complete answer myself while searching for a way to save *objects of an unknown type without using templates or void pointers which has been answered here. The solution is a bit dodgy, because you'll have to create a dummy parent which allows for certain conversions.
The idea is that you create a Parent and every object that is allowed to be pointed to must inherit from it. This way you can create a pointer as Parent *obj which can hold multiple types of objects, but of course only classes that inherit from Parent.
The same applies for function pointers. If you define your pointer as void (Parent::*func)() as member variable. You can ask the user a template function pointer template <class Class> setFunction( void (Class::*f)() ), which can hold any pointer to any class. Now you need to cast the function pointer to the desired class, Parent: static_cast<void(Parent::*)()>(f). Mind that this only works when Class inherits from Parent. Otherwise you'll get a compilation error.
Minimal Working Example
#include <iostream>
using namespace std;
// dummy class Parent
class Parent {};
// class A
class A : public Parent { // Mind the inheritance!
public:
A(int n) : num(n) {}
void print() { // <- function we want to point to
cout << "Number: " << num << endl;
}
int num;
}
// class B, will hold the 2 pointers
class B {
public:
B() {}
template <class Class> // will save the function and object pointer
void setFunction( void (Class::*func)(), Class *obj) {
function = static_cast<void(Parent::*)()>(func);
object = obj;
}
void execFunction() { // executes the function on the object
(object->*function)();
}
void (Parent::*function)(); // the function pointer
Parent *object; // the object pointer
}
int main() {
A a(5);
B b;
b.setFunction(&A::print, &a);
b.execFunction();
return 0;
}
I don't really like this solution. A better solution would be that class B could have a function where it returns a bool when the function needs to be executed. This way you could simply place an if statement in the main-function that executes the desired function.
A a(5);
B b;
while (;;) {
if (b.aTest())
a.print();
}
Where B::aTest() is declared as
bool B::aTest();
Hope this helps anyone that comes across the same problem. So it is perfectly possible but pretty dodgy in my opinion, and I don't encourage people using the first method.

Code executes derived class method, but gets default parameter from base class method

Can someone explain why the result of the code below would be "class B::1" ?
Why does the virtual method of derived class uses the default parameter of a base class and not his own? For me this is pretty strange. Thanks in advance!
Code:
#include <iostream>
using namespace std;
class A
{
public:
virtual void func(int a = 1)
{
cout << "class A::" << a;
}
};
class B : public A
{
public:
virtual void func(int a = 2)
{
cout << "class B::" << a;
}
};
int main()
{
A * a = new B;
a->func();
return 0;
}
Because default arguments are resolved according to the static type of this (ie, the type of the variable itself, like A& in A& a;).
Modifying your example slightly:
#include <iostream>
class A
{
public:
virtual void func(int a = 1)
{
std::cout << "class A::" << a << "\n";
}
};
class B : public A
{
public:
virtual void func(int a = 2)
{
std::cout << "class B::" << a << "\n";
}
};
void func(A& a) { a.func(); }
int main()
{
B b;
func(b);
b.func();
return 0;
}
We observe the following output:
class B::1
class B::2
In action at ideone.
It is not recommended that a virtual function change the default value for this reason. Unfortunately I don't know any compiler that warns on this construct.
The technical explication is that there are two ways of dealing with default argument:
create a new function to act as trampoline: void A::func() { func(1); }
add-in the missing argument at the call site a.func() => a.func(/*magic*/1)
If it were the former (and assuming that the A::func was declared virtual as well), then it would work like you expect. However the latter form was elected, either because issues with virtual were not foreseen at the time or because they were deemed inconsequential in face of the benefits (if any...).
Because default value is substituted during compilation and is taken from declaration, while real function to be called (A::func or B::func) is determined at runtime.
Because polymorphism in C++ takes effect at run-time, whereas the substitution of default parameters takes effect at compile-time. At compile time, the compiler does not know (and is not supposed to know) the dynamic type of the object to which the pointer a points. Hence, it takes the default argument for the only type it knows for a, which in your example is A *.
(This incidentally is also the reason default parameters are given in interfaces/headers rather than in implementations/definitions. The compiler never inserts the default parameter in the implementation's machine code, but only in the caller's machine code. Technically, the default parameter is the property of the caller; and the caller doesn't know -- and shouldn't need to know -- an object's dynamic type.)

The use case of 'this' pointer in C++

I understand the meaning of 'this', but I can't see the use case of it.
For the following example, I should teach the compiler if the parameter is the same as member variable, and I need this pointer.
#include <iostream>
using namespace std;
class AAA {
int x;
public:
int hello(int x) { this->x = x;}
int hello2(int y) {x = y;} // same as this->x = y
int getx() {return x;}
};
int main()
{
AAA a;
a.hello(10); // x <- 10
cout << a.getx();
a.hello2(20); // x <- 20
cout << a.getx();
}
What would be the use case for 'this' pointer other than this (contrived) example?
Added
Thanks for all the answers. Even though I make orangeoctopus' answer as accepted one, it's just because he got the most vote. I must say that all the answers are pretty useful, and give me better understanding.
Sometimes you want to return yourself from an operator, such as operator=
MyClass& operator=(const MyClass &rhs) {
// assign rhs into myself
return *this;
}
The 'this' pointer is useful if a method of the class needs to pass the instance (this) to another function.
It's useful if you need to pass a pointer to the current object to another function, or return it. The latter is used to allow stringing functions together:
Obj* Obj::addProperty(std::string str) {
// do stuff
return this;
}
obj->addProperty("foo")->addProperty("bar")->addProperty("baz");
In C++ it is not used very often. However, a very common use is for example in Qt, where you create a widget which has the current object as parent. For example, a window creates a button as its child:
QButton *button = new QButton(this);
When passing a reference to an object within one of its methods. For instance:
struct Event
{
EventProducer* source;
};
class SomeContrivedClass : public EventProducer
{
public:
void CreateEvent()
{
Event event;
event.source = this;
EventManager.ProcessEvent(event);
}
};
Besides obtaining a pointer to your own object to pass (or return) to other functions, and resolving that an identifier is a member even if it is hidden by a local variable, there is an really contrived usage to this in template programming. That use is converting a non-dependent name into a dependent name. Templates are verified in two passes, first before actual type substitution and then again after the type substitution.
If you declare a template class that derives from one of its type parameters you need to qualify access to the base class members so that the compiler bypasses the verification in the first pass and leaves the check for the second pass:
template <typename T>
struct test : T {
void f() {
// print(); // 1st pass Error, print is undefined
this->print(); // 1st pass Ok, print is dependent on T
}
};
struct printer {
void print() { std::cout << "print"; }
};
struct painter {
void paint() { std::cout << "paint"; }
};
int main() {
test<printer> t; // Instantiation, 2nd pass verifies that test<printer>::print is callable
t.f();
//test<painter> ouch; // 2nd pass error, test<painter>::print does not exist
}
The important bit is that since test inherits from T all references to this are dependent on the template argument T and as such the compiler assumes that it is correct and leaves the actual verification to the second stage. There are other solutions, like actually qualifying with the type that implements the method, as in:
template <typename T>
struct test2 : T {
void f() {
T::print(); // 1st pass Ok, print is dependent on T
}
};
But this can have the unwanted side effect that the compiler will statically dispatch the call to printer::print regardless of whether printer is a virtual method or not. So with printer::print being declared virtual, if a class derives from test<print> and implements print then that final overrider will be called, while if the same class derived from test2<print> the code would call printer::print.
// assumes printer::print is virtual
struct most_derived1 : test<printer> {
void print() { std::cout << "most derived"; }
};
struct most_derived2 : test2<printer> {
void print() { std::cout << "most derived"; }
};
int main() {
most_derived1 d1;
d1.f(); // "most derived"
most_derived2 d2;
d2.f(); // "print"
}
You can delete a dynamically created object by calling delete this from one of its member functions.
The this pointer is the pointer to the object itself. Consider for example the following method:
class AAA {
int x;
public:
int hello(int x) { some_method(this, x);}
};
void somefunc(AAA* a_p)
{
......
}
class AAA {
int x;
public:
int hello(int x) { this->x = x;}
int hello2(int y) {x = y;} // same as this.x = y
int getx() {return x;}
void DoSomething() { somefunc(this); }
};
this is implicit whenever you use a member function or variable without specifying it. Other than that, there are many, many situations in which you'll want to pass the current object to another function, or as a return value.
So, yeah, it's quite useful.
Sometimes you need to refer to "this" object itself, and sometimes you may need to disambiguate in cases where a local variable or a function parameter shadows a class member:
class Foo {
int i;
Foo* f() {
return this; // return the 'this' pointer
}
void g(){
j(this); // pass the 'this' pointer to some function j
}
void h(int i) {
this->i = i; // need to distinguish between class member 'i' and function parameter 'i'
}
};
The two first cases (f() and g() are the most meaningful cases. The third one could be avoided just by renaming the class member variable, but there's no way around using this in the first two cases.
Another possible use case of this:
#include <iostream>
using namespace std;
class A
{
public:
void foo()
{
cout << "foo() of A\n";
}
};
class B : A
{
public:
void foo()
{
((A *)this)->foo(); // Same as A::foo();
cout << "foo() of B\n";
}
};
int main()
{
B b;
b.foo();
return 0;
}
g++ this.cpp -o this
./this
foo() of A
foo() of B
One more use of this is to prevent crashes if a method is called on a method is called on a NULL pointer (similar to the NULL object pattern):
class Foo
{
public:
void Fn()
{
if (!this)
return;
...
}
};
...
void UseFoo(Foo* something)
{
something->Fn(); // will not crash if Foo == NULL
}
If this is useful or not depends on the context, but I've seen it occasionally and used it myself, too.
self-assignment protection