C++ function accepting any callable of a given templated signature - c++

If I understand it correctly, the standard way to write a function that accepts any callable as a parameter is:
template<typename Fn> void myFunction(Fn&& f) { ... }
I would like to do something similar, except I want to be able make Fn conform to a certain signature and I need to know the type of its parameter. For instance, something like:
template<typename T> void myFunction(std::function<void (T)>&& f) { ... }
The problem is this can't accept packaged_task or lambdas that capture move-only types like std::promise.
Update: Added an sample use case
Consider a simplified network request function:
template<typename T> void get(const Url& url,
const UrlQuery& params,
std::function<void (T)>&& callback) {
auto response = doGet(url, query);
callback(fromJson<T>(response));
}
This works reasonably well most of the time, but when I try to pass it a lambda that captures a std::promise it fails. I could use some workarounds to make that work, but I'm wondering if there is a more elegant way. Something closer to this pseudo code:
template<typename Fn<T>>
void get(const Url& url,
const UrlQuery& params,
Fn<T>&& callback) {
auto response = doGet(url, query);
callback(fromJson<T>(response));
}
Obviously that doesn't compile, but it sort of shows what I'd like.
To se the T parameter in the body of get while also keeping the Fn&& style parameter (eg. not specifying std::function or std::packaged_task as the type for callback) and also not needing to jump through any hoops when calling get.

The following, addressing the non-copyable-lambda part, works with MinGW g++ 7.2 and Visual C++ 2017:
#include <functional> // std::function
#include <memory> // std::shared_ptr
#include <utility> // std::move
template< class Type >
void foo( std::function<void (Type)>&& f )
{
f( 42 );
}
struct No_copy
{
No_copy( No_copy const& ) = delete;
auto operator=( No_copy const& ) -> No_copy& = delete;
No_copy() {}
No_copy( No_copy&& ) {}
auto operator=( No_copy&& ) -> No_copy& { return *this; }
};
template< class Type >
class Copyable
{
std::shared_ptr<Type> pf_;
public:
template< class... Args >
auto operator()( Args&&... args )
{ return (*pf_)( std::forward<Args>( args )... ); }
Copyable( Type&& o )
: pf_{ std::make_shared<Type>( std::move( o ) ) }
{}
};
// Necessary for Visual C++ 2017:
template< class Type >
auto copyable( Type&& o ) { return Copyable<Type>{ std::move( o ) }; }
#include <iostream>
using namespace std;
auto main()
-> int
{
No_copy o;
#ifdef DETAILED
auto lambda = [oh{move(o)}]( int x ){ cout << x << " " << &oh << endl; };
auto const c = copyable( move( lambda ) );
foo<int>( c );
#else
foo<int>( copyable( [oh{move(o)}]( int x ){ cout << x << " " << &oh << endl; } ) );
#endif
}
I haven't tried the particular types you mention, though.
Also, this code does not address the issue of deducing the argument type, if you want that (you'll have to add such deduction, if desired).
And, uhm, there's the issue of possible reference return type, not addressed here either.
:)

Related

Make foo(derived_object) call foo(Base const&) instead of template function?

Given this code:
template< class C >
void foo( C const& o ) { o.nosuch(); }
struct Base {};
void foo( Base const& ) {}
struct Derived: Base {};
auto main() -> int
{
Derived d;
foo( d ); // !Invokes template.
}
… I want the call to invoke the overload defined for Base, without having to define an overload or template specialization for Derived.
The goal is to be able to apply foo to all kinds of objects, not just Base (and Derived) objects, with a generic implementation for most kinds of objects.
It would also be nice if an answer explained exactly how overload resolution works in this case, versus how it works with a Derived overload defined.
In the code where this problem manifested, foo above is a function template n_items defined as follows:
template< class Type >
auto n_items( Type const& o )
-> size_t
{ return o.size(); }
template< size_t n >
auto n_items( std::bitset<n> const& o )
-> size_t
{ return o.count(); } // Corresponds to std::set<int>::size()
template< class Type, size_t n >
constexpr
auto n_items( Raw_array_of_<n, Type> const& a )
-> size_t
{ return static_size( a ); }
And the intent is that this should be a catch-all for types that don't define their own n_items overloads.
And for a base and derived class, it should be enough that the base class defines a custom n_items; it would be very redundant to have to define it for every derived class.
How overload resolution works
First we do name lookup and template type deduction. For foo(d), this gives us two options:
foo(Derived const&), with [C = Derived]
foo(Base const&)
These are our viable candidates.
Then we determine which one of the overloads is the best viable candidate. This is done first by looking at conversion sequences. In this case, (1) is an Exact Match whereas (2) involves a derived-to-base conversion which has Conversion rank (see this table). Since that ranks worse, candidate (1) is preferred and is thus deemed the best viable candidate.
How to do what you really want
The simplest way is to simply add a third overload for Derived:
foo(Derived const&)
Here, both (1) and (3) would be equivalent in terms of conversion sequence. But functions that aren't templates are preferred to functions that are templates (think of it as picking the most specific option), so (3) would be selected.
But you don't want to do that. So the options are either: make (1) not work for Derived or make (2) work for Derived too in a way that's preferred.
Disable the general template
We can use SFINAE to simply exclude anything derived from Base:
template <class T, class = std::enable_if_t<!std::is_convertible<T*, Base*>::value>
void foo(T const& ); // new (1)
void foo(Base const& ); // same (2)
Now, (1) is no longer a viable candidate for the match, so (2) is trivally preferred.
Redo the overloads so that the Base is preferred
Taking a tip out of Xeo's book, we can restructure the overloads thusly:
template <int I> struct choice : choice<I + 1> { };
template <> struct choice<10> { };
struct otherwise { otherwise(...) {} };
template <class T> void foo(T const& val) { foo_impl(val, choice<0>{}); }
And now we can prefer those types derived from Base:
template <class T, class = std::enable_if_t<std::is_convertible<T*, Base*>::value>>
void foo_impl(T const& val, choice<0> ); // new (2)
template <class T>
void foo_impl(T const& val, otherwise ); // new (1)
This changes the mechanics of how overload resolution works and is worth going through into the separate cases.
Calling foo(d) means we're calling foo_impl(d, choice<0> ) and gives us two viable candidates:
foo_impl(Derived const&, choice<0> ), with [T = Derived]
foo_impl(Derived const&, otherwise ), with [T = Derived]
Here, the first argument is identical, but for the second argument, the first overload is an Exact Match while the second argument requires a Conversion via a variadic argument. otherwise will always be the word choice as a result, so the first overload is preferred. Exactly what we want.
Calling foo(not_a_base), on the other hand, would only give us one viable candidate:
foo_impl(NotABase const&, otherwise ), with [T = NotABase]
The other one was removed due to the deduction failure. So this is trivially the best viable candidate, and again we get exactly what we want.
For your specific question, I'd write something like:
template <class T>
size_t n_items(T const& cont) { return n_items(cont, choice<0>{}); }
with:
// has count?
template <class T>
auto n_items(T const& cont, choice<0> ) -> decltype(cont.count()) {
return cont.count();
}
// else, has size?
template <class T>
auto n_items(T const& cont, choice<1> ) -> decltype(cont.size()) {
return cont.size();
}
// else, use static_size
template <class T>
size_t n_items(T const& cont, otherwise )
return static_size(cont);
}
Put all the non-template functions in some namespace:
namespace Foo {
void foo( Base const& ) {}
}
Then define the function template thusly:
template <typename C>
auto foo_aux(C const& c, int) -> decltype(Foo::foo(c)) {
return Foo::foo(c);}
template <typename C>
void foo_aux(C const& c, ...) {
c.nosuch();}
template <typename C>
void foo(C const& c) {foo_aux(c, 0);}
Demo. This will call the general overload if and only if none of the non-template overloads match (or are ambiguous).
The main technical problem is that a general function template foo (say), instantiated for Derived argument, is a better match than the overload for Base argument.
Brute force solution (redundancy).
One simple possible solution is to require overloads of all the relevant functions for every class derived from a Base.
However, this breaks the DRY rule, Don't Repeat Yourself.
Needless redundancy in code leads to maintenance problems.
Namespace for SFINAE.
Another possible solution, suggested by Columbo, is to “put all the non-template functions in some [specific single] namespace”, which allows a general function template to use SFINAE to detect if a relevant overload exists.
This solution avoids the redundancy, and as I recall it is the kind of solution used for boost::intrusive_ptr, that client code must specialize the functionality in some specific namespace.
However, since it imposes a restriction on client code it feels not perfect to me.
Extra argument to direct overload resolution.
A third possible solution, suggested by Barry, is to let the base class implementation have an associated overload, or just a differently named function, that has an extra argument that serves to direct the overload resolution, and that is called by by a general function template.
This is technically a solution but IMO it's not clean: the client code invocations don't match the overloads that must be provided.
And so again there is a potential maintenance problem.
Invoking the function template from a simple converting overload.
Johannes Schaub suggested a fourth possible solution, which allows clean, simple client code, namely to let an ordinary overload call the function template, but where that general implementation overload has a formal argument type that
introduces a user defined conversion, which makes this a worse match than direct per-class overloads, and
has a templated constructor that picks up the actual argument type.
Johannes' original ingenious in-comment idea assumed a fixed function result type and exactly one argument. Generalizing that short idea description to arbitrary result type was not entirely trivial for me because that result type can depend on the actual argument, and one tends to first of all try to automate things like that. Likewise, generalizing to arbitrary number of arguments, with the first one acting as a this argument, was not 100% trivial for me. Johannes would no doubt have no problems doing this, and probably in a more neat way than I could do it. Anyway, my code:
#include <functional>
#include <utility>
//-------------------------------------- General machinery:
template< class Impl_func, class Result, class... Args >
class Invoker_of_
{
private:
std::function< auto(Args...) -> Result > f_;
public:
auto operator()( Args... args ) const -> Result { return f_( args... ); }
template< class Type >
Invoker_of_( Type& o )
: f_(
[&]( Args... args )
-> Result
{ return Impl_func{}.operator()( o, args... ); }
)
{}
};
//-------------------------------------- General template 1 (foo):
struct Foo_impl
{
template< class Type >
auto operator()( Type& o )
-> int
{ return o.foomethod(); }
};
auto foo( Invoker_of_<Foo_impl, int> const invoker )
-> int
{ return invoker(); }
//-------------------------------------- General template 2 (bar):
struct Bar_impl
{
template< class Type >
auto operator()( Type& o, int const arg1 )
-> int
{ return o.barmethod( arg1 ); }
};
auto bar( Invoker_of_<Bar_impl, int, int> const invoker, int const arg1 )
-> int
{ return invoker( arg1 ); }
//--------------------------------------- Usage examples:
struct Base {};
auto foo( Base const& ) -> int { return 101;}
auto bar( Base const&, int x ) -> int { return x + 2; }
struct Derived: Base {};
struct Other
{
auto foomethod() -> int { return 201; }
auto barmethod( int const x ) -> int { return x + 2; }
};
//--------------------------------------- Test driver:
#include <iostream>
using namespace std;
auto main() -> int
{
Derived d;
int const r1 = foo( d ); // OK, invokes non-template overload.
int const r2 = bar( d, 100 ); // OK, invokes non-template overload.
cout << r1 << " " << r2 << endl;
Other o;
int const r3 = foo( o ); // OK, invokes the general template.
int const r4 = bar( o, 200 ); // OK, invokes the general template.
cout << r3 << " " << r4 << endl;
}
I have not attempted to support rvalue reference arguments.
Output:
101 102
201 202
A variation Johannes Schaub's suggestion, which appears to yield the most clean usage, written up as code for the example at the start:
//-------------------------------------- Machinery:
template< class Type >
auto foo_impl( Type& o ) -> int { return o.method(); }
struct Invoker_of_foo_impl
{
int result;
template< class Type >
Invoker_of_foo_impl( Type& o ): result( foo_impl( o ) ) {}
};
auto foo( Invoker_of_foo_impl const invoker ) -> int { return invoker.result; }
//--------------------------------------- Usage:
struct Base {};
auto foo( Base const& ) -> int { return 6*7;}
struct Derived: Base {};
struct Other { auto method() -> int { return 0b101010; } };
auto main() -> int
{
Derived d;
foo( d ); // OK, invokes non-template.
Other o;
foo( o ); // OK, invokes template
}
I'm not sure I got the problem, but can't you use simply SFINAE and the is_base_of trait?
Using them, catch all functions are automatically excluded when the function resolution takes place for a class that is derived from Base and the best match is the non-template one.
Moreover, such a solution looks to me as far simpler than all the other... That's why I'm pretty sure that I didn't get the problem!! :-)
Anyway, it follows a working example:
#include<type_traits>
#include<iostream>
struct Base {};
auto foo( Base const& ) -> int {return 101;}
auto bar( Base const&, int x ) -> int {return x + 2; }
template<class T, typename = typename std::enable_if<not std::is_base_of<Base, T>::value>::type>
auto foo(T & t) -> int {
return t.foomethod();
}
template<class T, typename = typename std::enable_if<not std::is_base_of<Base, T>::value>::type>
auto bar(T & t, int i) -> int {
return t.barmethod(i);
}
struct Derived: Base {};
struct Other
{
auto foomethod() -> int { return 201; }
auto barmethod( int const x ) -> int { return x + 2; }
};
#include <iostream>
using namespace std;
auto main() -> int
{
Derived d;
int const r1 = foo( d ); // Invokes the Base arg overload.
int const r2 = bar( d, 100 ); // Invokes the Base arg overload.
cout << r1 << " " << r2 << endl;
Other o;
int const r3 = foo( o ); // Invokes the general implementation.
int const r4 = bar( o, 200 ); // Invokes the general implementation.
cout << r3 << " " << r4 << endl;
}
Let me know if I've misunderstood the problem, in that case I'm dropping the answer.

Make `foo(derived_object, x)` call `foo(Base const&, X)` instead of template function? [duplicate]

Given this code:
template< class C >
void foo( C const& o ) { o.nosuch(); }
struct Base {};
void foo( Base const& ) {}
struct Derived: Base {};
auto main() -> int
{
Derived d;
foo( d ); // !Invokes template.
}
… I want the call to invoke the overload defined for Base, without having to define an overload or template specialization for Derived.
The goal is to be able to apply foo to all kinds of objects, not just Base (and Derived) objects, with a generic implementation for most kinds of objects.
It would also be nice if an answer explained exactly how overload resolution works in this case, versus how it works with a Derived overload defined.
In the code where this problem manifested, foo above is a function template n_items defined as follows:
template< class Type >
auto n_items( Type const& o )
-> size_t
{ return o.size(); }
template< size_t n >
auto n_items( std::bitset<n> const& o )
-> size_t
{ return o.count(); } // Corresponds to std::set<int>::size()
template< class Type, size_t n >
constexpr
auto n_items( Raw_array_of_<n, Type> const& a )
-> size_t
{ return static_size( a ); }
And the intent is that this should be a catch-all for types that don't define their own n_items overloads.
And for a base and derived class, it should be enough that the base class defines a custom n_items; it would be very redundant to have to define it for every derived class.
How overload resolution works
First we do name lookup and template type deduction. For foo(d), this gives us two options:
foo(Derived const&), with [C = Derived]
foo(Base const&)
These are our viable candidates.
Then we determine which one of the overloads is the best viable candidate. This is done first by looking at conversion sequences. In this case, (1) is an Exact Match whereas (2) involves a derived-to-base conversion which has Conversion rank (see this table). Since that ranks worse, candidate (1) is preferred and is thus deemed the best viable candidate.
How to do what you really want
The simplest way is to simply add a third overload for Derived:
foo(Derived const&)
Here, both (1) and (3) would be equivalent in terms of conversion sequence. But functions that aren't templates are preferred to functions that are templates (think of it as picking the most specific option), so (3) would be selected.
But you don't want to do that. So the options are either: make (1) not work for Derived or make (2) work for Derived too in a way that's preferred.
Disable the general template
We can use SFINAE to simply exclude anything derived from Base:
template <class T, class = std::enable_if_t<!std::is_convertible<T*, Base*>::value>
void foo(T const& ); // new (1)
void foo(Base const& ); // same (2)
Now, (1) is no longer a viable candidate for the match, so (2) is trivally preferred.
Redo the overloads so that the Base is preferred
Taking a tip out of Xeo's book, we can restructure the overloads thusly:
template <int I> struct choice : choice<I + 1> { };
template <> struct choice<10> { };
struct otherwise { otherwise(...) {} };
template <class T> void foo(T const& val) { foo_impl(val, choice<0>{}); }
And now we can prefer those types derived from Base:
template <class T, class = std::enable_if_t<std::is_convertible<T*, Base*>::value>>
void foo_impl(T const& val, choice<0> ); // new (2)
template <class T>
void foo_impl(T const& val, otherwise ); // new (1)
This changes the mechanics of how overload resolution works and is worth going through into the separate cases.
Calling foo(d) means we're calling foo_impl(d, choice<0> ) and gives us two viable candidates:
foo_impl(Derived const&, choice<0> ), with [T = Derived]
foo_impl(Derived const&, otherwise ), with [T = Derived]
Here, the first argument is identical, but for the second argument, the first overload is an Exact Match while the second argument requires a Conversion via a variadic argument. otherwise will always be the word choice as a result, so the first overload is preferred. Exactly what we want.
Calling foo(not_a_base), on the other hand, would only give us one viable candidate:
foo_impl(NotABase const&, otherwise ), with [T = NotABase]
The other one was removed due to the deduction failure. So this is trivially the best viable candidate, and again we get exactly what we want.
For your specific question, I'd write something like:
template <class T>
size_t n_items(T const& cont) { return n_items(cont, choice<0>{}); }
with:
// has count?
template <class T>
auto n_items(T const& cont, choice<0> ) -> decltype(cont.count()) {
return cont.count();
}
// else, has size?
template <class T>
auto n_items(T const& cont, choice<1> ) -> decltype(cont.size()) {
return cont.size();
}
// else, use static_size
template <class T>
size_t n_items(T const& cont, otherwise )
return static_size(cont);
}
Put all the non-template functions in some namespace:
namespace Foo {
void foo( Base const& ) {}
}
Then define the function template thusly:
template <typename C>
auto foo_aux(C const& c, int) -> decltype(Foo::foo(c)) {
return Foo::foo(c);}
template <typename C>
void foo_aux(C const& c, ...) {
c.nosuch();}
template <typename C>
void foo(C const& c) {foo_aux(c, 0);}
Demo. This will call the general overload if and only if none of the non-template overloads match (or are ambiguous).
The main technical problem is that a general function template foo (say), instantiated for Derived argument, is a better match than the overload for Base argument.
Brute force solution (redundancy).
One simple possible solution is to require overloads of all the relevant functions for every class derived from a Base.
However, this breaks the DRY rule, Don't Repeat Yourself.
Needless redundancy in code leads to maintenance problems.
Namespace for SFINAE.
Another possible solution, suggested by Columbo, is to “put all the non-template functions in some [specific single] namespace”, which allows a general function template to use SFINAE to detect if a relevant overload exists.
This solution avoids the redundancy, and as I recall it is the kind of solution used for boost::intrusive_ptr, that client code must specialize the functionality in some specific namespace.
However, since it imposes a restriction on client code it feels not perfect to me.
Extra argument to direct overload resolution.
A third possible solution, suggested by Barry, is to let the base class implementation have an associated overload, or just a differently named function, that has an extra argument that serves to direct the overload resolution, and that is called by by a general function template.
This is technically a solution but IMO it's not clean: the client code invocations don't match the overloads that must be provided.
And so again there is a potential maintenance problem.
Invoking the function template from a simple converting overload.
Johannes Schaub suggested a fourth possible solution, which allows clean, simple client code, namely to let an ordinary overload call the function template, but where that general implementation overload has a formal argument type that
introduces a user defined conversion, which makes this a worse match than direct per-class overloads, and
has a templated constructor that picks up the actual argument type.
Johannes' original ingenious in-comment idea assumed a fixed function result type and exactly one argument. Generalizing that short idea description to arbitrary result type was not entirely trivial for me because that result type can depend on the actual argument, and one tends to first of all try to automate things like that. Likewise, generalizing to arbitrary number of arguments, with the first one acting as a this argument, was not 100% trivial for me. Johannes would no doubt have no problems doing this, and probably in a more neat way than I could do it. Anyway, my code:
#include <functional>
#include <utility>
//-------------------------------------- General machinery:
template< class Impl_func, class Result, class... Args >
class Invoker_of_
{
private:
std::function< auto(Args...) -> Result > f_;
public:
auto operator()( Args... args ) const -> Result { return f_( args... ); }
template< class Type >
Invoker_of_( Type& o )
: f_(
[&]( Args... args )
-> Result
{ return Impl_func{}.operator()( o, args... ); }
)
{}
};
//-------------------------------------- General template 1 (foo):
struct Foo_impl
{
template< class Type >
auto operator()( Type& o )
-> int
{ return o.foomethod(); }
};
auto foo( Invoker_of_<Foo_impl, int> const invoker )
-> int
{ return invoker(); }
//-------------------------------------- General template 2 (bar):
struct Bar_impl
{
template< class Type >
auto operator()( Type& o, int const arg1 )
-> int
{ return o.barmethod( arg1 ); }
};
auto bar( Invoker_of_<Bar_impl, int, int> const invoker, int const arg1 )
-> int
{ return invoker( arg1 ); }
//--------------------------------------- Usage examples:
struct Base {};
auto foo( Base const& ) -> int { return 101;}
auto bar( Base const&, int x ) -> int { return x + 2; }
struct Derived: Base {};
struct Other
{
auto foomethod() -> int { return 201; }
auto barmethod( int const x ) -> int { return x + 2; }
};
//--------------------------------------- Test driver:
#include <iostream>
using namespace std;
auto main() -> int
{
Derived d;
int const r1 = foo( d ); // OK, invokes non-template overload.
int const r2 = bar( d, 100 ); // OK, invokes non-template overload.
cout << r1 << " " << r2 << endl;
Other o;
int const r3 = foo( o ); // OK, invokes the general template.
int const r4 = bar( o, 200 ); // OK, invokes the general template.
cout << r3 << " " << r4 << endl;
}
I have not attempted to support rvalue reference arguments.
Output:
101 102
201 202
A variation Johannes Schaub's suggestion, which appears to yield the most clean usage, written up as code for the example at the start:
//-------------------------------------- Machinery:
template< class Type >
auto foo_impl( Type& o ) -> int { return o.method(); }
struct Invoker_of_foo_impl
{
int result;
template< class Type >
Invoker_of_foo_impl( Type& o ): result( foo_impl( o ) ) {}
};
auto foo( Invoker_of_foo_impl const invoker ) -> int { return invoker.result; }
//--------------------------------------- Usage:
struct Base {};
auto foo( Base const& ) -> int { return 6*7;}
struct Derived: Base {};
struct Other { auto method() -> int { return 0b101010; } };
auto main() -> int
{
Derived d;
foo( d ); // OK, invokes non-template.
Other o;
foo( o ); // OK, invokes template
}
I'm not sure I got the problem, but can't you use simply SFINAE and the is_base_of trait?
Using them, catch all functions are automatically excluded when the function resolution takes place for a class that is derived from Base and the best match is the non-template one.
Moreover, such a solution looks to me as far simpler than all the other... That's why I'm pretty sure that I didn't get the problem!! :-)
Anyway, it follows a working example:
#include<type_traits>
#include<iostream>
struct Base {};
auto foo( Base const& ) -> int {return 101;}
auto bar( Base const&, int x ) -> int {return x + 2; }
template<class T, typename = typename std::enable_if<not std::is_base_of<Base, T>::value>::type>
auto foo(T & t) -> int {
return t.foomethod();
}
template<class T, typename = typename std::enable_if<not std::is_base_of<Base, T>::value>::type>
auto bar(T & t, int i) -> int {
return t.barmethod(i);
}
struct Derived: Base {};
struct Other
{
auto foomethod() -> int { return 201; }
auto barmethod( int const x ) -> int { return x + 2; }
};
#include <iostream>
using namespace std;
auto main() -> int
{
Derived d;
int const r1 = foo( d ); // Invokes the Base arg overload.
int const r2 = bar( d, 100 ); // Invokes the Base arg overload.
cout << r1 << " " << r2 << endl;
Other o;
int const r3 = foo( o ); // Invokes the general implementation.
int const r4 = bar( o, 200 ); // Invokes the general implementation.
cout << r3 << " " << r4 << endl;
}
Let me know if I've misunderstood the problem, in that case I'm dropping the answer.

Alternative for std::function that works with move lambdas? [duplicate]

This question already has answers here:
How to create an std::function from a move-capturing lambda expression?
(3 answers)
Closed 2 years ago.
In C++14, a lambda expression can capture variables by moving from them using capture initializers. However, this makes the resulting closure object non-copyable. If I have an existing function that takes a std::function argument (that I cannot change), I cannot pass the closure object, because std::function's constructor requires the given functor to be CopyConstructible.
#include <iostream>
#include <memory>
void doit(std::function<void()> f) {
f();
}
int main()
{
std::unique_ptr<int> p(new int(5));
doit([p = std::move(p)] () { std::cout << *p << std::endl; });
}
This gives the following errors:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:1911:10: error:
call to implicitly-deleted copy constructor of '<lambda at test.cpp:10:7>'
new _Functor(*__source._M_access<_Functor*>());
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:1946:8: note: in
instantiation of member function 'std::_Function_base::_Base_manager<<lambda at test.cpp:10:7>
>::_M_clone' requested here
_M_clone(__dest, __source, _Local_storage());
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:2457:33: note: in
instantiation of member function 'std::_Function_base::_Base_manager<<lambda at test.cpp:10:7>
>::_M_manager' requested here
_M_manager = &_My_handler::_M_manager;
^
test.cpp:10:7: note: in instantiation of function template specialization 'std::function<void
()>::function<<lambda at test.cpp:10:7>, void>' requested here
doit([p = std::move(p)] () { std::cout << *p << std::endl; });
^
test.cpp:10:8: note: copy constructor of '' is implicitly deleted because field '' has a deleted
copy constructor
doit([p = std::move(p)] () { std::cout << *p << std::endl; });
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/unique_ptr.h:273:7: note:
'unique_ptr' has been explicitly marked deleted here
unique_ptr(const unique_ptr&) = delete;
^
Is there a reasonable workaround?
Testing with Ubuntu clang version 3.5-1~exp1 (trunk)
There is this approach:
template< typename signature >
struct make_copyable_function_helper;
template< typename R, typename... Args >
struct make_copyable_function_helper<R(Args...)> {
template<typename input>
std::function<R(Args...)> operator()( input&& i ) const {
auto ptr = std::make_shared< typename std::decay<input>::type >( std::forward<input>(i) );
return [ptr]( Args... args )->R {
return (*ptr)(std::forward<Args>(args)...);
};
}
};
template< typename signature, typename input >
std::function<signature> make_copyable_function( input && i ) {
return make_copyable_function_helper<signature>()( std::forward<input>(i) );
}
where we make a shared pointer to our data, then make a copyable lambda that captures that shared pointer, then we wrap that copyable lambda into a std::function of the requested signature.
In your case above, you'd just:
doit( make_copyable_function<void()>( [p = std::move(p)] () { std::cout << *p << std::endl; } ) );
A slightly more advanced version defers the type erasure and adds a layer of perfect forwarding to reduce overhead:
template<typename input>
struct copyable_function {
typedef typename std::decay<input>::type stored_input;
template<typename... Args>
auto operator()( Args&&... args )->
decltype( std::declval<input&>()(std::forward<Args>(args)...) )
{
return (*ptr)(std::forward<Args>(args));
}
copyable_function( input&& i ):ptr( std::make_shared<stored_input>( std::forward<input>(i) ) ) {}
copyable_function( copyable_function const& ) = default;
private:
std::shared_ptr<stored_input> ptr;
};
template<typename input>
copyable_function<input> make_copyable_function( input&& i ) {
return {std::forward<input>(i)};
}
which does not require you to pass the signature in, and can be slightly more efficient in a few cases, but uses more obscure techniques.
In C++14 with this can be made even more brief:
template< class F >
auto make_copyable_function( F&& f ) {
using dF=std::decay_t<F>;
auto spf = std::make_shared<dF>( std::forward<F>(f) );
return [spf](auto&&... args)->decltype(auto) {
return (*spf)( decltype(args)(args)... );
};
}
doing away with the need for the helper type entirely.
If lifetime of the closure object isn't an issue, you could pass it in a reference wrapper:
int main()
{
std::unique_ptr<int> p(new int(5));
auto f = [p = std::move(p)]{
std::cout << *p << std::endl;
};
doit(std::cref(f));
}
This obviously doesn't apply to every scenario, but it's fine for your example program.
EDIT: Taking a glance at N3797 (C++14 working draft) § 20.9.11.2.1 [func.wrap.func.con] p7, the CopyConstructible requirement is still there. I wonder if there's a technical reason that can't be loosened to MoveConstructible, or if the committee just didn't get around to it?
EDIT: Answering my own question: std::function is CopyConstructible, so the wrapped functor needs to be CopyConstructible as well.
If you know you aren't actually going to copy your function object then you can just wrap it in a type that makes the compiler think it's copyable:
struct ThrowOnCopy {
ThrowOnCopy() = default;
ThrowOnCopy(const ThrowOnCopy&) { throw std::logic_error("Oops!"); }
ThrowOnCopy(ThrowOnCopy&&) = default;
ThrowOnCopy& operator=(ThrowOnCopy&&) = default;
};
template<typename T>
struct FakeCopyable : ThrowOnCopy
{
FakeCopyable(T&& t) : target(std::forward<T>(t)) { }
FakeCopyable(FakeCopyable&&) = default;
FakeCopyable(const FakeCopyable& other)
: ThrowOnCopy(other), // this will throw
target(std::move(const_cast<T&>(other.target))) // never reached
{ }
template<typename... Args>
auto operator()(Args&&... a)
{ return target(std::forward<Args>(a)...); }
T target;
};
template<typename T>
FakeCopyable<T>
fake_copyable(T&& t)
{ return { std::forward<T>(t) }; }
// ...
doit( fake_copyable([p = std::move(p)] () { std::cout << *p << std::endl; }) );
The function template fake_copyable creates a wrapper which is CopyConstructible according to the compiler (and <type_traits>) but cannot be copied at run-time.
If you store a FakeCopyable<X> in a std::function and then end up copying the std::function you will get a std::logic_error thrown, but if you only move the std::function everything will work OK.
The target(std::move(const_cast<T&>(other.target))) looks worrying, but that initializer will never run, because the base class initializer will throw first. So the worrying const_cast never really happens, it just keeps the compiler happy.

Retrieve pointer to best match from overload set without calling

For various reasons I need to use 2 phase construction, furthermore the last phase is deferred and performed by another thread, some context:
...
#define BOOST_PP_LOCAL_MACRO(n) \
template < typename ConnectionType, BOOST_PP_ENUM_PARAMS(n, typename T) > \
boost::shared_ptr< ConnectionType > Connect( BOOST_PP_ENUM_BINARY_PARAMS(n, T, arg) ) \
{ \
boost::shared_ptr< ConnectionType > con( boost::make_shared< ConnectionType >() ); \
boost::mutex::scoped_lock sl( m_AddNetworkJobMutex ); \
m_NetworkJobs.push_back( boost::bind( static_cast< void ( ConnectionType::* )( BOOST_PP_ENUM_PARAMS(n,T) ) >( &ConnectionType::Init ), con, BOOST_PP_ENUM_PARAMS(n, arg) ) ); \
return con; \
}
#define BOOST_PP_LOCAL_LIMITS (1, 5)
#include BOOST_PP_LOCAL_ITERATE()
...
The problem here is that I want to select the best match possible from the overload set for ConnectionType::Init, but the cast is distinct and can't find a perfect match even if some of the arguments are convertible. So the questions becomes: Is it possible to somehow get the type & pointer to the best match from the overload set without actually calling it? Can't use anything which isn't available in C++03.
You can leverage lazy evaluation expression templates.
AFAIK bind expressions are precisely in that family (as are Boost Proto epxressions, Spirit Grammar parse expressions etc.).
Update finally got my act together. However, it only works with callable objects with overloaded operator(). I suppose you can use something like this as glue?
I now show both C++03 and C++11 proofs-of-concept that might help get something of a glue functor built-up around this
The C++03 is near equivalent (see the // TODO in the code)
The C++03 version depends on Boost Typeof and Boost Bind (see Boost Utility doc for result_of for backgrounds on result types of polymorphic function objects)
Both versions live on IdeOne
C++03 (live on https://ideone.com/VHcEC)
Here is a partial port of the C++11 demo (below) into C++03 + Boost:
#include <string>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/typeof/typeof.hpp>
struct overloaded
{
typedef int result_type;
int operator()(const std::string& s) const { return 1; }
int operator()(double d) const { return 2; }
};
struct factory
{
template <typename T> struct result { typedef BOOST_TYPEOF_TPL(boost::bind(overloaded(), T())) type; };
template <typename T>
typename result<T>::type operator()(const T& t) const
{
return boost::bind(overloaded(), t);
}
};
int main()
{
overloaded foo;
// based on local bind expression:
BOOST_AUTO(unresolved, boost::bind(foo, _1));
std::cout << unresolved("3.14") << std::endl; // should print 1
std::cout << unresolved(3.14) << std::endl; // should print 2
// based on a factory function template
factory makefoo;
std::string str("3.14"); // TODO get rid of this explicit instanciation?
std::cout << makefoo(str)() << std::endl; // should print 1
std::cout << makefoo(3.14)() << std::endl; // should print 2
}
C++11 (live on https://ideone.com/JILEA)
As a simple example, this should work alright:
#include <string>
#include <iostream>
#include <functional>
using namespace std::placeholders;
struct overloaded
{
int operator()(const std::string& s) const { return 1; }
int operator()(double d) const { return 2; }
};
template <typename T>
auto makefoo(const T& t) -> decltype(std::bind(overloaded(), t))
{
return std::bind(overloaded(), t);
}
int main()
{
overloaded foo;
// based on local bind expression:
auto unresolved = std::bind(foo, _1);
std::cout << unresolved(3.14) << std::endl; // should print 2
std::cout << unresolved("3.14") << std::endl; // should print 1
// based on a factory function template
std::cout << makefoo(3.14)() << std::endl; // should print 2
std::cout << makefoo("3.14")() << std::endl; // should print 1
}

How to write a boost::lambda functor that returns a new functor

How can I write a lambda expression with two placeholders, one for the callable object, and one for the function argument, such that supplying the callable object first returns a unary function.
In the example below, generate should be a lambda expression with the first placeholder for the callable object itself, and the second placeholder for the argument. Calling generate(c) should return a unary function that is only missing the function call argument. In fact, it somehow returns type bool already, as proved by the static assert.
#include <boost/lambda/bind.hpp>
struct Arg {
};
struct Callable : std::unary_function<Arg, bool> {
bool operator()( Arg const& a ) const { return true; }
};
int main( int argc, const char* argv[] ) {
BOOST_AUTO(generate, boost::lambda::bind(boost::lambda::_1, boost::lambda::protect(boost::lambda::_1)));
Callable c;
BOOST_AUTO(fn, generate(c));
BOOST_STATIC_ASSERT((boost::is_same<BOOST_TYPEOF(fn), bool>::value));
Arg a;
bool b = fn(a);
_ASSERT(b==true);
}
If using Boost.Phoenix the answer would have been a little easier:
#include <boost/phoenix/phoenix.hpp>
struct callable
{
typedef bool result_type;
bool operator()(int) const
{
return true;
}
};
int main()
{
using phx::bind;
using phx::lambda;
using phx::arg_names::_1;
using phx::local_names::_a;
auto generate = lambda(_a = _1)[bind(_a, _1)];
auto fn = generate(callable());
bool b = fn(8);
}
Not that this solution is far more generic than the version posted by the OT. It can be used with any unary function object, no matter what argument, no matter what return type.
The downside, you need to use the current boost trunk ...
I have solved my own problem, albeit not as elegantly as I had hoped:
struct FCreateBind {
typedef boost::_bi::bind_t<bool, Callable, boost::_bi::list2<boost::arg<1>, boost::arg<2> > > result_type;
result_type operator()( Callable const& c ) const {
return boost::bind<bool>(c, _1);
}
};
BOOST_AUTO(generate, boost::bind(FCreateBind(), _1));
BOOST_AUTO(fn, generate(Callable());
bool b = fn(Arg());
Of course, in this simple example I could just write BOOST_AUTO(generate, boost::lambda_1) since Callable itself is the callable object. But I was looking for a way to set the arguments of Callable beforehand so the generated function fn is a nullary function. This solution would let me do this inside FCreateBind.
FCreateBind can probably be eliminated as well, but I have not yet figured out how to define the pointer to the overloaded global function boost::bind.
Though I'm not 100% sure I understand the question, the following code
might meet your purpose:
template< class R >
struct FCreateBind {
typedef boost::function< R() > result_type;
template< class T, class U >
result_type operator()( T const& x, U const& y ) const {
return boost::bind( x, y );
}
};
int main() {
BOOST_AUTO( generate, boost::bind( FCreateBind< bool >(), Callable(), _1 ) );
BOOST_AUTO( fn, generate( Arg() ) );
bool b = fn();
}
That being said, probably this isn't as pretty as the questioner
expects...
As you mentioned, if we specify one of the overloads of boost::bind
explicitly, FCreateBind wouldn't be needed.
However, as far as I saw, there seems not to be the portable way to specify
the overload.
So, in this case, probably we have to depend on the internal of boost.
For your information, the following code could be compiled when I tested:
int main() {
namespace bb = boost::_bi; // Sorry, for brevity
bb::bind_t< bb::unspecified, Callable, bb::list1< bb::value< Arg > > >
(*bi)( Callable, Arg ) = boost::bind< bb::unspecified, Callable, Arg >;
BOOST_AUTO( generate, boost::bind( bi, Callable(), _1 ) );
BOOST_AUTO( fn, generate( Arg() ) );
bool b = fn();
}
Hope this helps