I have a templated class which instantiates an internal object of the template type and its constructor forwards the arguments to the internal object.
template<typename T>
struct B
{
template<typename... Args>
B(Args&&... args) : m(std::forward<Args>(args)...) {}
B(const B& b) = default;
B(B&& b) noexcept = default;
void operator()() { m(); }
T m;
};
Also this class is callable and it simply delegates the call to its internal member. The reason it is callable is because I want to pass it around as a std::function. The problem is that the compiler doesn't let me initialize a std::function with an object of type B:
struct A
{
void operator()() { std::cout << "A()\n"; }
};
void foo()
{
B<A> b;
std::function<void()> fb = b; //Error
}
The error is a cryptic one:
error: no matching function for call to ‘A::A(B&)’
B(Args&&... args) : a(std::forward<Args>(args)...) {}
Nowhere in my code have I made a call to A::A(B&). I expect std::function to call B::B(B&) constructor to copy the data from b to fb.
Note that this only happens because of the variadic template constructor of B. The following code compiles fine:
A a;
std::function<void()> fa = a;
The instantion of
with
Args... == B&
is a better match for copying a non-const lvalueB
than either your copy or move constructor. Instantiating that is likewhich uses
A::A(B&)
You could either add an overload
B(B&) = default;
, or add some SFINAE to your template constructor.