if I declare:
class Avoidance : public Schema<std_msgs::String,prog1::Command>{
and I try to
void*(Schema<std_msgs::String,prog1::Command>::*pt)();
pt=&Avoidance::frontBusy;
compiler report me
error: cannot convert ‘void* (Avoidance::*)()’
to
‘void* (Schema<std_msgs::String_<std::allocator<void> >, prog1::Command_<std::allocator<void> > >::*)()’ in assignment
why? Avoidance inherits from
Schema<std_msgs::String,prog1::Command>
then Avoidance IS Schema<.....>
That's not how member function pointers work. If frontBusy is a base function, you need to type the pointer appropriately. The dispatch will still work as expected, though!
Here's a basic example:
struct A { virtual void f() = 0; };
struct B : A { virtual void f() { } };
void dispatch(void (A::*pf)(), A & a)
{ // ^^^^^
(a.*pf)();
}
int main()
{
B x;
dispatch(&A::f, x); // calls x.B::f()
} // ^^^^^
So, in your case you want:
void (Schema<std_msgs::String,prog1::Command>::*p)()
= &Schema<std_msgs::String,prog1::Command>::frontBusy;
Getting rid of templates to simplify, suppose you have
class B {
public:
void f();
};
class D : public B {
public:
void g();
};
It might seem a little backwards at first, but you can cast void (B::*)() to void (D::*)(), but you cannot cast void (D::*)() to void (B::*)(). This makes sense when you think about how they would later be used.
void test() {
void (D::*p)() = &B::f; // OK!
void (B::*q)() = &D::g; // ERROR!
B b;
D d;
(d.*p)(); // Calls B::f on `d`. Okay, `B::f` is an inherited member.
(b.*q)(); // Calls D::g on `b`?? But that's not a member of `b` at all!
}
Related
Consider the following standard CRTP example:
#include <iostream>
template<class Derived>
struct Base {
void f() { static_cast<Derived *>(this)->f(); }
void g() { static_cast<Derived *>(this)->g(); }
};
struct Foo : public Base<Foo> {
void f() { std::cout << 42 << std::endl; }
};
int main() {
Foo foo;
foo.f(); // just OK
foo.g(); // this will stack overflow and segfault
}
If this was regular virtual inheritance I could have mark virtual f and g methods as pure like
struct Base {
virtual void f() = 0;
virtual void g() = 0;
};
and get a compile time error about Foo being abstract. But CRTP offers no such protection. Can I implement it somehow? Runtime check is acceptable too. I thought about comparing this->f pointer with static_cast<Derived *>(this)->f, but didn't manage to make it work.
You can assert at compile time that the two pointers to member functions are different, e.g.:
template<class Derived>
struct Base {
void g() {
static_assert(&Derived::g != &Base<Derived>::g,
"Derived classes must implement g().");
static_cast<Derived *>(this)->g();
}
};
Here is another possibility:
#include <iostream>
template<class Derived>
struct Base {
auto f() { return static_cast<Derived *>(this)->f(); }
auto g() { return static_cast<Derived *>(this)->g(); }
};
struct Foo : public Base<Foo> {
void f() { std::cout << 42 << std::endl; }
};
int main() {
Foo foo;
foo.f(); // just OK
foo.g(); // this will not compile
}
For GCC, it gives a pretty clear error message ("error: use of 'auto Base::g() [with Derived = Foo]' before deduction of 'auto'"), while for Clang, it gives a slightly less readable infinitely recursing template instantiation of Base<Foo>::g, with g instantiating itself but eventually ending in an error.
You could use this solution, you can have pure "non-virtual abstract" function, and it maps as much as possible to CRTP this recommendation of H. Sutter:
template<class Derived>
struct Base
{
void f(){static_cast<Derived*>(this)->do_f();}
void g(){static_cast<Derived*>(this)->do_g();}
private:
//Derived must implement do_f
void do_f()=delete;
//do_g as a default implementation
void do_g(){}
};
struct derived
:Base<derived>
{
friend struct Base<derived>;
private:
void do_f(){}
};
You could consider doing something like this instead. You can make Derived a member and either supply it as a template parameter directly each time you instantiate a Base or else use a type alias as I have done in this example:
template<class Derived>
struct Base {
void f() { d.f(); }
void g() { d.g(); }
private:
Derived d;
};
struct FooImpl {
void f() { std::cout << 42 << std::endl; }
};
using Foo = Base<FooImpl>;
int main() {
Foo foo;
foo.f(); // OK
foo.g(); // compile time error
}
Of course Derived is no longer derived so you might pick a better name for it.
Consider the following standard CRTP example:
#include <iostream>
template<class Derived>
struct Base {
void f() { static_cast<Derived *>(this)->f(); }
void g() { static_cast<Derived *>(this)->g(); }
};
struct Foo : public Base<Foo> {
void f() { std::cout << 42 << std::endl; }
};
int main() {
Foo foo;
foo.f(); // just OK
foo.g(); // this will stack overflow and segfault
}
If this was regular virtual inheritance I could have mark virtual f and g methods as pure like
struct Base {
virtual void f() = 0;
virtual void g() = 0;
};
and get a compile time error about Foo being abstract. But CRTP offers no such protection. Can I implement it somehow? Runtime check is acceptable too. I thought about comparing this->f pointer with static_cast<Derived *>(this)->f, but didn't manage to make it work.
You can assert at compile time that the two pointers to member functions are different, e.g.:
template<class Derived>
struct Base {
void g() {
static_assert(&Derived::g != &Base<Derived>::g,
"Derived classes must implement g().");
static_cast<Derived *>(this)->g();
}
};
Here is another possibility:
#include <iostream>
template<class Derived>
struct Base {
auto f() { return static_cast<Derived *>(this)->f(); }
auto g() { return static_cast<Derived *>(this)->g(); }
};
struct Foo : public Base<Foo> {
void f() { std::cout << 42 << std::endl; }
};
int main() {
Foo foo;
foo.f(); // just OK
foo.g(); // this will not compile
}
For GCC, it gives a pretty clear error message ("error: use of 'auto Base::g() [with Derived = Foo]' before deduction of 'auto'"), while for Clang, it gives a slightly less readable infinitely recursing template instantiation of Base<Foo>::g, with g instantiating itself but eventually ending in an error.
You could use this solution, you can have pure "non-virtual abstract" function, and it maps as much as possible to CRTP this recommendation of H. Sutter:
template<class Derived>
struct Base
{
void f(){static_cast<Derived*>(this)->do_f();}
void g(){static_cast<Derived*>(this)->do_g();}
private:
//Derived must implement do_f
void do_f()=delete;
//do_g as a default implementation
void do_g(){}
};
struct derived
:Base<derived>
{
friend struct Base<derived>;
private:
void do_f(){}
};
You could consider doing something like this instead. You can make Derived a member and either supply it as a template parameter directly each time you instantiate a Base or else use a type alias as I have done in this example:
template<class Derived>
struct Base {
void f() { d.f(); }
void g() { d.g(); }
private:
Derived d;
};
struct FooImpl {
void f() { std::cout << 42 << std::endl; }
};
using Foo = Base<FooImpl>;
int main() {
Foo foo;
foo.f(); // OK
foo.g(); // compile time error
}
Of course Derived is no longer derived so you might pick a better name for it.
This code gives me error in VS2015 update 1:
error C2893: Failed to specialize function template 'unknown-type
std::invoke(_Callable &&,_Types &&...)'
#include <iostream>
#include <functional>
using std::cout;
class A
{
public:
virtual void init()
{
cout << "A";
};
};
class B
{
public:
virtual void init()
{
cout << "B";
};
};
class C : private A, private B
{
std::function<void()> a_init = &A::init;
std::function<void()> b_init = &B::init;
public:
void call()
{
a_init();
b_init();
}
};
int main()
{
C c;
c.call();
return 0;
}
Any ideas if that's VS compiler is buggy or my code?
EDIT
#include "stdafx.h"
#include <functional>
class A
{
public:
virtual void inita()
{
cout << "A";
};
};
class B
{
public:
virtual void initb()
{
cout << "B";
};
};
class C : private virtual A, private virtual B
{
/*std::function<void()> a_init = &A::init;
std::function<void()> b_init = &B::init;*/
public:
void call()
{
inita();
}
};
You're trying to assign non-static member functions into a std::function taking no arguments. That cannot work, since non-static member functions have an implicit this parameter.
How to solve this depends on what you want to do. If you want to call the stored function on an arbitrary object supplied at call time, you'll need to change the std::function signature:
std::function<void(A*)> a_init = &A::init;
void call()
{
a_init(this); // or some other object of type A on which you want to invoke it
}
[Live example]
If, on the other hand, you want to call it without arguments, you will have to bind an object of type A into the std::function at initialisation:
std::function<void()> a_init = std::bind(&A::init, this);
void call()
{
a_init()
};
[Live example]
Change the function from virtual to static and the code will work. You need a specific instance of a class to call a non-static function.
On the other hand, if you wish to use non-static function, you can add the following constructor:
C(A &a, B &b)
{
a_init = std::bind(&A::init, &a);
b_init = std::bind(&B::init, &b);
}
and then use it in main like this:
A a;
B b;
C c(a, b);
c.call();
EDIT:
If public inheritance is acceptable option, then you can do it even simpler.
Constructor:
C()
{
a_init = std::bind(&A::init, this);
b_init = std::bind(&B::init, this);
}
Usage:
C c;
c.call();
There is a class
class A {
public:
A() {};
private:
void func1(int) {};
void func2(int) {};
};
I want to add a function pointer which will be set in constructor and points to func1 or func2.
So I can call this pointer (as class member) from every class procedure and set this pointer in constructor.
How can I do it?
class A {
public:
A(bool b) : func_ptr_(b ? &A::func1 : &A::func2) {};
void func(int i) {this->*func_ptr(i);}
private:
typedef void (A::*func_ptr_t_)();
func_ptr_t_ func_ptr_;
void func1(int) {};
void func2(int) {};
};
That said, polymorphism might be a better way to do whatever you want to do with this.
Add a member variable
void (A::*ptr)();
set it in the constructor
ptr=&A::func1;
(or use the initializer list) and call it in methods of A:
(this->*ptr)();
I compiled and ran this code. The various members need to be public so you can pass them into the constructor. Otherwise, here you go.
However, I agree with other posters that this is almost definitely a bad thing to do. ;) Just make invoke pure virtual, and then make two subclasses of A which each override invoke().
#include <iostream>
using namespace std;
class A;
typedef void(A::*MyFunc)(int) ;
class A {
public:
A() {}
A(MyFunc fp): fp(fp) {}
void invoke(int a)
{
(this->*fp)(a);
}
void func1(int a) { cout << "func1 " << a << endl; }
void func2(int a) { cout << "func2 " << a << endl; }
private:
MyFunc fp;
};
int main()
{
A* a = new A( & A::func1 );
a->invoke(5);
A* b = new A( & A::func2 );
b->invoke(6);
}
See boost::function for a way to handle function and class member pointers in a more OO/C++ manner.
For example (from the documentation) :
struct X
{
int foo(int);
};
boost::function<int (X*, int)> f;
f = &X::foo;
X x;
f(&x, 5);
I suggest you use functor(or function object), rather than function pointer, because the former is safer, and function pointer can be difficult or awkward to pass a state into or out of the callback function
A functor is basically a re-implementation of operator() of class A, for very detailed description please refer to Wikipedia: http://en.wikipedia.org/wiki/Function_object
The code should be something like this:
class A {
public:
A() {};
void operator()(int function_index, int parameter) {
if(function_index == 1)
func1(parameter);
else if(function_index == 2)
func2(parameter);
else
{ //do your other handling operation
}
}
private:
void func1( int ) {};
void func2( int) {};
};
By using that class:
A a;
a(1, 123); //calling func1
a(2, 321); //calling func2
Why do you think it's a bad thing to do. I just need one function pointer and I don't want to create two subclasses for this. So why is it so bad?
Some example...
class A; // forward declaration
typedef void (A::*func_type)(int);
class A {
public:
A() {
func_ptr = &A::func1;
}
void test_call(int a) {
(this->*func_ptr)(a);
}
private:
func_type func_ptr;
void func1(int) {}
void func2(int) {}
};
#include<iostream>
using namespace std;
class Abs
{
public:
virtual void hi()=0;
};
class B:public Abs
{
public:
void hi() {cout<<"B Hi"<<endl;}
void bye() {cout<<"B Bye"<<endl;}
};
class C:public Abs
{
public:
void hi() {cout<<"C Hi"<<endl;}
void sayonara() {cout<<"C Sayonara"<<endl;}
};
int main()
{
Abs *bb=new B;
bb->bye();
Abs *cc=new C;
cc->sayonara();
}//main
The compiler says
test2.cpp: In function ‘int main()’:
test2.cpp:26: error: ‘class Abs’ has no member named ‘bye’
test2.cpp:28: error: ‘class Abs’ has no member named ‘sayonara’
Because of this problem, I'll have to add functions to the Abs class each time I create a new derived class which inherits from it (Upcasting is compulsory for me to do. The program I'm planning requires it to be so). I don't want to touch the base class once it's created.
Doesn't this problem violate the principle that once you make a base class, you won't have to modify it ever. Any way to resolve this problem?
p.s: I've seen the factory design pattern and the prototype design patterns, but both of them can't seem to be able to solve it.
This is defeating the purpose of inheritance and abstract interfaces. bye and sayonara both do the same thing (saying goodbye), only in different languages. This means you should have an abstract say_goodbye method that gets overridden for subclasses. I suppose this is a simplified example, so maybe you could describe your actual scenario so we can provide more specific help.
Edit If you want to create a copy of the derived class through an abstract interface, check out this question. If you want to explicitly access the different attributes of your subclasses, you should be asking your self if subclassing es even appropriate here, since your classes don't seem to have much in common.
Well, i'm not sure to understand exactly what you want (and why you want it that way) but:
int main()
{
Abs *bb=new B;
static_cast<B*>(bb)->bye();
Abs *cc=new C;
static_cast<C*>(cc)->sayonara();
}//main
Will work.
You just have to be sure that bb is really a B* before you static_cast.
You may also use dynamic_cast which will return a null pointer if bb is not of the correct type.
int main()
{
B *bb = new B;
bb->bye();
C *cc=new C;
cc->sayonara();
}//main
This way modifications in the base class are no longer needed :)
Dynamic casting is a sensible option. If you're religious about dynamic casts, you can use the visitor design pattern:
struct Abs;
struct B;
struct C;
struct Visitor
{
virtual ~Visitor() {}
// Provide sensible default actions
virtual void visit(Abs&) const { throw "not implemented"; }
virtual void visit(B& b) const { visit(static_cast<Abs&>(b)); }
virtual void visit(C& c) const { visit(static_cast<Abs&>(c)); }
};
struct Abs
{
virtual ~Abs() {}
virtual void hi() = 0;
virtual void accept(Visitor const& v) { v.visit(*this); }
};
struct B : Abs
{
void hi() { ... }
void accept(Visitor const& v) { v.visit(*this); }
void bye() { ... }
};
struct C : Abs
{
void hi() { ... }
void accept(Visitor const& v) { v.visit(*this); }
void sayonara() { ... }
};
struct DoSayonara : Visitor
{
void visit(C& c) const { c.sayonara(); }
};
struct DoBye : Visitor
{
void visit(B& b) const { b.bye(); }
};
struct ByeOrSayonara : Visitor
{
void visit(B& b) const { b.bye(); }
void visit(C& c) const { c.sayonara(); }
};
and then you use
Abs* b = new B(); Abs* c = new C();
b->accept(DoSayonara()); // Throw an exception
c->accept(DoSayonara()); // Do what is expected
Do this only when you really need it.
If upcasting is compulsory and you need to call methods defined in the subclasses then You're Doing It Wrong.
However, at a given point in time, you either know that an object is a specific subclass, in which case you can dynamically cast to that type, or you don't and can't be sure you can call the function.
Assuming this is related to your other question, I've tried to explain a way to implement that particular problem in a different manner there.