Most terse and reusable way of wrapping template or overloaded functions in function objects
You can create a macro like
#define FUNCTORIZE(func) [](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);}
which will let you wrap any callable into a closure object. You would use it like
auto constexpr predObj = FUNCTORIZE(pred);
How to declare the template argument for an overloaded function
You can wrap the function in a lambda, or pass a function pointer after casting it to the type of the overload you want to call or explicitly specify the template parameter:
use_funct([](){ do_something (); });
use_funct(static_cast<void(*)()>(do_something));
use_funct<void()>(do_something);
Wrapping it in a lambda has the advantage, that it is possible to defer overload resolution to use_func
. For example:
void do_something(int) {}
void do_something(double) {}
template<typename F> void use_funct(F funct) {
funct(1); // calls do_something(int)
funct(1.0); // calls do_something(double)
}
int main() {
use_funct([](auto x){ do_something (x); });
}
[...] possibly without referring to a function pointer?
I am not sure what you mean or why you want to avoid that. void()
is the type of the function, not a function pointer. If you care about spelling out the type, you can use an alias:
using func_type = void();
use_funct<func_type>(do_something);
Does Boost (or another library) offer a way to lift the name of a constructor-less class into a function object that uses aggregate initialization?
If you want a function object that constructs an object of some type T
given some parameters, even if T
is an aggregate, that's not difficult to write in C++17:
template<typename T>
struct lifted_construct
{
template<typename ...Args>
T operator() (Args&& ...args)
{
if constexpr(std::is_aggregate_v<T>)
{
return T{std::forward<Args>(args)...};
}
else
{
return T(std::forward<Args>(args)...);
}
}
};
Of course, in C++20, you can use ()
syntax even for aggregates.
How to use std::max or std::min as function parameter
The following works:
void foo (std::function<double const&(double const&, double const&)>) {}
void foo2 (double const&(double const&, double const&)){}
int main () {
foo((double const&(*)(double const&, double const&))(std::max<double>));
foo2(std::max<double>);
}
Note that we always need to use std::max<double>
.
In the call to foo
, as it takes a std::function
, theres no good way the compiler can work out which overloaded version of std::max
to use and so you need to cast it to the correct type.
For the second one, as foo2
takes the raw function, it just works.
Note that I've explicitly use double const&
, as the plain T
versions (as in not having the const&
) of std::max
take an initialiser list and so there's no way to cast it to what you need.
So to get it working with the foo
as written, you'll have to use a lambda or overload or wrapper of some sort.
So the simplest way would be to use the knowledge above of what does work, and add an overload:
void foo(double const&(*func)(double const&, double const&) )
{
foo([&func](double a, double b){return func(a, b);});
}
and then foo(std::max<double>);
will work
Related Topics
How to Calculate the Angle from Rotation Matrix
Easiest Way of Using Min Priority Queue with Key Update in C++
Why Would Anyone Use Set Instead of Unordered_Set
Where Are the Man Pages for C++
Difference Between C++11 Std::Bind and Boost::Bind
General Use Cases for C++ Containers
What Is _Declspec and When Do I Need to Use It
Why Do You Use Typedef When Declaring an Enum in C++
Using Maven for C/C++ Projects
How to Embed Webkit into My C/C++/Win32 Application
Throw New Std::Exception VS Throw Std::Exception
Initializing the Size of a C++ Vector
Do All Virtual Functions Need to Be Implemented in Derived Classes
C++ Priority_Queue with Lambda Comparator Error
What's the Difference Between Opening a File with iOS::Binary or iOS::Out or Both