Reputation: 24675
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();
}
};
Upvotes: 3
Views: 2819
Reputation: 4153
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();
Upvotes: 1
Reputation: 171127
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
}
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()
};
Upvotes: 8