Single-Expression Member Function Pointers - c++

The standard way to represent a pointer to a member function for a specific instance of a class is to use a pointer to the instance and a pointer to the member function:
void Execute(Foo* inst, void (Foo::*func)(int), int x) {
(inst->*func)(x);
}
...
Execute(foo, &Foo::Bar, 42);
Is there any way to define Execute such that the function pointer is represented as a single expression?
For example:
void Execute(SomeType v, int x) {
(v.inst->*v.func)(x);
}
...
Execute(foo->Bar, 42);
My main problem is that in my specific case, Foo is nested under a long and unstable chain of namespaces, so an actual invocation using the standard syntax looks more like Execute(foo, &hello::darkness::my::old::friend::Foo::Bar, 42). I almost always have a local foo instance however, from which I can refer to the much simpler foo->Bar(42). I need to do some extra bookkeeping though, which is why I need to wrap the call in something like Execute. using directives and namespace aliases are not an option unfortunately.

Is there any way to define Execute such that the function pointer is represented as a single expression?
Yes. Change the function to use std::function or a callable template parameter, eg:
#include <functional>
void Execute(std::function<void(int)> v, int x)
{
v(x);
}
template<typename Callable>
void Execute(Callable v, int x)
{
v(x);
}
And then you can use std::bind() or a lambda for the input expression, eg:
#include <functional>
using namespace std::placeholders;
using FooType = std::remove_reference<decltype(*foo)>::type;
Execute(std::bind(&FooType::Bar, foo, _1), 42);
// or, in C++20 and later:
Execute(std::bind_front(&FooType::Bar, foo), 42);
Execute([=](int x){ foo->Bar(x); }, 42);
Also, just to mention that in C++Builder specifically, there is a __closure extension that allows calling member methods without having to qualify the class type at all, eg:
typedef void (__closure *TExecuteCallable)(int);
void Execute(TExecuteCallable v, int x)
{
v(x);
}
...
Execute(foo->Bar, 42);
// or
Execute(&(foo->Bar), 42);

Related

How to declare the template argument for an overloaded function

I have a fairly big project that, regarding this question,
I can summarize with
this structure:
void do_something()
{
//...
}
template<typename F> void use_funct(F funct)
{
// ...
funct();
}
int main()
{
// ...
use_funct(do_something);
}
All is working ok until someone (me) decides to reformat a little
minimizing some functions, rewriting
as this minimum reproducible example:
void do_something(const int a, const int b)
{
//...
}
void do_something()
{
//...
do_something(1,2);
}
template<typename F> void use_funct(F funct)
{
// ...
funct();
}
int main()
{
// ...
use_funct(do_something);
}
And now the code doesn't compile with
error: no matching function for call
where use_funct is instantiated.
Since the error message was not so clear to me
and the changes were a lot I wasted a considerable
amount of time to understand that the compiler
couldn't deduce the template parameter
because do_something could now refer to
any of the overloaded functions.
I removed the ambiguity changing the function name,
but I wonder if there's the possibility to avoid
this error in the future not relying on template
argument deduction.
How could I specify in this case the template argument for do_something(), possibly without referring to a function pointer?
I haven't the slightest idea to express explicitly:
use_funct<-the-one-with-no-arguments->(do_something);
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);

How to curry a method on an object for passing it as a C-style callback?

Let's assume we have the following class A:
class A
{
public:
void sum(int x);
};
And we have a function f, which gets a C-style callback with one parameter of type int and calls it:
typedef void (*Callback)(int);
void f(Callback cb)
{
cb(5);
}
Is there any way in C++ to curry a method A::print on an object of type A and pass it to the function f? Something like this:
void main()
{
A a;
auto curry_a = ??; // something like curry_a = [&](int x) { a.sum(x) };
f(curry_a);
}
std::bind and lambda-function are not a solution, because they create objects of type std::function<> with overloaded operator(). It looks like currying in C++, but it cannot be used in my case. I need a real function pointer, i.e. generate code in real time.
You are out of luck, it can't be done in a satisfactory way: The only thing that is exactly a C-compatible function pointer is a function (or class-function but not instance function).
So, you'd have to create a function that fixes a parameter, like the this of a member function. The only way to set this parameter is through a global variable:
A *instance;
void (A::*a_fun)(int);
void applicator(int arg) { instance->*a_fun(arg); }
//...
int main() {
A a;
instance = &a;
a_fun = &A::sum;
f(applicator);
// ...
That is the only way to provide context to a plain function, through global variables.

C++ Functions with lambdas as arguments

I have an overload function, with the following signatures:
void Foo(const std::function<void(int )> &func);
void Foo(const std::function<void(int, int)> &func);
And when I want to use Foo() with lambdas, I'll have to do something like this:
Foo((std::function<void(int )>) [] (int i ) { /* do something */ });
Foo((std::function<void(int, int)>) [] (int i, int j) { /* do something */ });
Both of which are not so user-friendly. It'd be a lot easier to use the function without having to add the casting "(std::function<...>)" before the lambdas - like this:
Foo([] (int i ) { /* do something */ }); // executes the 1st Foo()
Foo([] (int i, int j) { /* do something */ }); // executes the 2nd Foo()
So, I need another overload, that accept lambda as its argument, and which automatically casts the lambda to one of the above signatures. How can this be done? Or, is it possible in the first place?
template <typename Function> void Foo(Function function) {
// insert code here: should be something like
// - check the signature of the 'function'; and
// - call 'Foo()' corresponding to the signature
}
Please help.
PS. I'm using VS2010.
If your lambda does not capture any variables—that is, it begins with []—then it is convertible to a function pointer, and you can declare Foo like so:
void Foo(void(*func)(int));
void Foo(void(*func)(int, int));
If you want to keep the std::function versions, you can have these versions forward to that one. If you don’t want to implement them separately, I think a variadic template would do nicely:
template<class... Args>
void Foo(void(*func)(Args...)) {
return std::function<void(Args...)>(func);
}
If your lambdas capture variables, then they’re not convertible to function pointers, and you’ll need to wrap them in std::function yourself.
Lambda's convert to std::function<> implicitly, there's no explicit conversion needed.
std::function<void(int, int)> func = [](int a, int b){ printf("Hello Lambda world!"); };
func(1, 2);
Ah, you're trying to get a const reference to it. Why though? You should be better off with a right-hand reference (as it's a temporary) or a copy. In both of those cases it should implicitly convert as well...

Best practice for local variable scope in a C++ callback

I have a functioning C++ callback function, triggered by a user 'mouse down' event. (The IDE is VS2010.)
With each call, I'd like to increment a simple count variable that is local to the callback's scope. Simply put, what is the 'best practices' way to do this?
Thanks in advance for any opinions or directives.
Replace your callback function with a functor - they can store state. An example functor:
#include <iostream>
#include <memory>
class Functor
{
private:
std::shared_ptr<int> m_count;
public:
Functor()
: m_count(new int(0))
{}
void operator()()
{
++(*m_count);
// do other stuff...
}
int count() const
{
return *m_count;
}
};
template <typename F>
void f(F callback)
{
// do stuff
callback();
// do other stuff
}
int main()
{
Functor callback;
f(callback);
f(callback);
std::cout << callback.count(); // prints 2
return 0;
}
Note the use of a shared_ptr inside the functor - this is because f has a local copy of the functor (note the pass-by-value) and you want that copy to share its int with the functor to which you have access. Note also that f has to take its argument by value, since you want to support all callables, and not just functors.

How do I assign an alias to a function name in C++?

It's easy to create a new name for a type, a variable or a namespace. But how do I assign a new name to a function? For example, I want to use the name holler for printf. #define is obvious... any other way?
Solutions:
#define holler printf
void (*p)() = fn; //function pointer
void (&r)() = fn; //function reference
inline void g(){ f(); }
There are different approaches:
With C++11 with non-template non-overloaded functions you can simply use:
const auto& new_fn_name = old_fn_name;
If this function has multiple overloads you should use static_cast:
const auto& new_fn_name = static_cast<OVERLOADED_FN_TYPE>(old_fn_name);
Example: there are two overloads of function std::stoi
int stoi (const string&, size_t*, int);
int stoi (const wstring&, size_t*, int);
If you want to make an alias to the first version you should use the following:
const auto& new_fn_name = static_cast<int(*)(const string&, size_t*, int)>(std::stoi);
Note: there is no way to make an alias to overloaded function such that all its overloaded versions work, so you should always specify which exact function overload you want.
With C++14 you can go even further with constexpr template variables. That allows you to alias templated functions:
template<typename T>
constexpr void old_function(/* args */);
template<typename T>
constexpr auto alias_to_old = old_function<T>;
Moreover, starting with C++11 you have a function called std::mem_fn that allows to alias member functions. See the following example:
struct A {
void f(int i) {
std::cout << "Argument: " << i << '\n';
}
};
A a;
auto greet = std::mem_fn(&A::f); // alias to member function
// prints "Argument: 5"
greet(a, 5); // you should provide an object each time you use this alias
// if you want to bind an object permanently use `std::bind`
greet_a = std::bind(greet, a, std::placeholders::_1);
greet_a(3); // equivalent to greet(a, 3) => a.f(3);
You can create a function pointer or a function reference:
void fn()
{
}
//...
void (*p)() = fn;//function pointer
void (&r)() = fn;//function reference
typedef int (*printf_alias)(const char*, ...);
printf_alias holler = std::printf;
Should do you fine.
int (*holler)(const char*, ...) = std::printf;
Use an inline wrapper. You get both APIs, but keep the single implementation.
With C++14 generic lambdas, I was able to do the following, which should also work when the target function has multiple overloads:
constexpr auto holler = [] ( auto &&...args ) {
return printf( std::forward<decltype(args)>( args )... );
};
From fluentcpp : ALIAS_TEMPLATE_FUNCTION(f, g)
#define ALIAS_TEMPLATE_FUNCTION(highLevelF, lowLevelF) \
template<typename... Args> \
inline auto highLevelF(Args&&... args) -> decltype(lowLevelF(std::forward<Args>(args)...)) \
{ \
return lowLevelF(std::forward<Args>(args)...); \
}
It is worth mentioning here IMO that while the original question (and great answers) are definitely useful if you want to rename a function (there are good reasons to do so!), if all you want to do is strip out a deep namespace but keep the name, there is the using keyword for this:
namespace deep {
namespace naming {
namespace convention {
void myFunction(int a, char b) {}
}
}
}
int main(void){
// A pain to write it all out every time
deep::naming::convention::myFunction(5, 'c');
// Using keyword can be done this way
using deep::naming::convention::myFunction;
myFunction(5, 'c'); // Same as above
}
This also has the advantage of it being confined to a scope, though you could always use it at the top level of a file. I often use this for cout and endl so I don't need to bring in ALL of std with the classic using namespace std; at the top of a file, but also useful if you're using something like std::this_thread::sleep_for() a lot in one file or function, but not everywhere, and not any other functions from the namespace. As always, it's discouraged to use it in .h files, or you'll pollute the global namespace.
This is not the same as the "renaming" above, but is often what is really wanted.