Why aren't these function signatures treated the same? - c++

I must be misunderstanding something because I thought the two cases are the same:
#include <iostream>
void function() { std::cout << "Hi\n"; }
int main()
{
std::vector<void(*)()> funcPtrVec;
std::vector<void()> funcVec;
funcPtrVec.push_back(function); // Works
funcVec.push_back(function); // Works
auto lambdaFunc = []() { std::cout << "Hi\n"; };
funcPtrVec.push_back(lambdaFunc); // Works
funcVec.push_back(lambdaFunc); // Doesn't work
}
Now, in both cases my compiler says that the function signatures are the same, void function() and void lambdaFunc(). I really thought that when a lambda function doesn't capture anything it behaves like a free function, which the same signatures would seem to support. Also, I guess I'm confused even more due to the fact that in the following all seem to be treated the same, as if decaying to the same thing:
void function() { std::cout << "Hi\n"; }
void funcTakingFunc(void()) {}
void funcTakingFuncPtr(void(*)()) {}
int main()
{
auto lambdaFunc = []() { std::cout << "Hi\n"; };
void(*funcPtr)() = lambdaFunc; // Works
funcTakingFuncPtr(lambdaFunc); // Works
funcTakingFuncPtr(funcPtr); // Works
funcTakingFunc(lambdaFunc); // Works
funcTakingFunc(funcPtr); // Works
// They all work
}
So as far as I can see the only distinction between the function and the function pointer made is when given as a template argument to vector. This obviously means I don't understand templates well, but what's the reason for this? Because the two really seem the same from the examples I tried.

std::vector<void()> is not allowed; the type must be an object type, and a function type is not an object type.
There are various parts of the specification of vector requirements we could identify as being violated by a non-object type; the most obvious is the default allocator. In the table in [allocator.requirements]/2 it is specified that the type the allocator is for must be an object type.

Related

C++ distinguish Lambdas from Function pointers inside a vector

I'm writing a little event manager class where I store some function pointers inside a vector. I use std::function<void(int)> as vector type, I tested inserting inside it lambdas and normal functions and it works:
void t(int p){
/*things*/
}
[...]
event.bind([](int p){/*things*/});
event.bind(t);
Now, (at a certain point I need to delete lambdas but not functions,) my question is:
Is it possible to distinguish lambdas from functions? If yes, how?
EDIT:
Since I clarified my doubts, this question becomes just what the title says
The real answer is: you don't want to do this. It defeats the point of type-erasing functors if you actually want to know the original type also in case of whatever. This just smells like bad design.
What you are potentially looking for is std::function::target_type. This is a way to pull out the underlying type_info of the target function that the function object is storing. Each type_info has a name(), which can be demangled. Note that this is a very deep rabbit hole and you're basically going to have to hard-code all sorts of weird edge-cases. As I've been doing thanks to Yakk's very loving help.
Different compilers mangle their lambda names differently, so this approach doesn't even resemble portability. Quick checking shows that clang throws in a $ while gcc throws {lambda...#d}, So we can attempt to take advantage of that by writing something like:
bool is_identifier(std::string const& id) {
return id == "(anonymous namespace)" ||
(std::all_of(id.begin(), id.end(),
[](char c){
return isdigit(c) || isalpha(c) || c == '_';
}) && !isdigit(id[0]));
}
bool is_lambda(const std::type_info& info)
{
std::unique_ptr<char, decltype(&std::free)> own {
abi::__cxa_demangle(info.name(), nullptr, nullptr, nullptr),
std::free
};
std::string name = own ? own.get() : info.name();
// drop leading namespaces... if they are valid namespace names
std::size_t idx;
while ((idx = name.find("::")) != std::string::npos) {
if (!is_identifier(name.substr(0, idx))) {
return false;
}
else {
name = name.substr(idx+2);
}
}
#if defined(__clang__)
return name[0] == '$';
#elif defined(__GNUC__)
return name.find("{lambda") == 0;
#else
// I dunno?
return false;
#endif
}
And then throw that in your standard erase-remove idiom:
void foo(int ) { }
void bar(int ) { }
long quux(long x) { return x; }
int main()
{
std::vector<std::function<void(int)>> v;
v.push_back(foo);
v.push_back(bar);
v.push_back(quux);
v.push_back([](int i) { std::cout << i << '\n';});
std::cout << v.size() << std::endl; // prints 4
v.erase(
std::remove_if(
v.begin(),
v.end(),
[](std::function<void(int)> const& f){
return is_lambda(f.target_type());
}),
v.end()
);
std::cout << v.size() << std::endl; // prints 3
}
No, not in general.
A std::function<void(int)> can store a function pointer to any function that can be called by passing a single rvalue int. There are an infinite number of such signatures.
The type of a lambda is an unique anonymous class for each declaration. Two distinct lambdas do not share any type relationship.
You can determine of a std::function<void(int)> stores a variable of a specific type, but in both the function pointer and lambda case there is an unbounded number of different types that can be stored in the std::function to consider. And you can only test for "exactly equal to a type".
You can access the type id information, but there is no portable representation there, and generally using that information for anything other than identity matching (and related) or debugging is a bad idea.
Now, a restricted version of the question (can you tell if a std::function<void(int)> contains a function pointer of type void(*)(int)) is easy to solve. But in general, doing so remains a bad idea: first, because it is delicate (code far away from the point you use it, like a subtle change to the function signature, can break things), and second, inspecting and changing your behavior based on the type stored in a std::function should only be done in extreme corner cases (usually involving updating your code from using void* style callbacks to std::function style callbacks).
Be it a function pointer or lambda, it ends up as a std::function<void(int)> in the vector. It is then std::function<void(int)>'s responsibility to manage the function pointer or lambda, not yours. That means, you just remove the std::function<void(int)>s you want from the vector. The destructor of std::function<void(int)> knows how to do things right. In your case, that would be doing nothing with function pointers and invoking the destructor of lambdas. std::function<void(int)> enables you to treat different things in a nice and uniform way. Don't misuse it.
NOTE: This answer presupposes that there is a finite, distinct number of function signatures that may be assigned as event handlers. It assumes that assigning any-old function with the wrong signature is a mistake.
You can use std::function::target to determine which ones are the function pointers and by process of elimination figure out which ones must be the lambdas:
void func1(int) {}
void func2(double) {}
int main()
{
std::vector<std::function<void(int)>> events;
events.push_back(func1);
events.push_back([](int){});
events.push_back(func2);
for(auto& e: events)
{
if(e.target<void(*)(int)>())
std::cout << "funcion int" << '\n';
else if(e.target<void(*)(double)>())
std::cout << "funcion double" << '\n';
else
std::cout << "must be lambda" << '\n';
}
}
This works because std::function::target returns a null pointer if the parameter type doesn't match.
Single variable example:
void func(int) {}
int main()
{
std::function<void(int)> f = func;
if(f.target<void(*)(int)>())
std::cout << "not a lambda" << '\n';
}

Storing and calling functions of different arguments in one function container

Here is a sample design code of what I want to achieve. Basically I wanna store handler functions for different handlerNames and these handler functions can be of variable arguments.
The handler functions should be called on events with the required arguments are passed with Script::Handle(...)
How can I achieve this? Maybe its possible with Variadic Templates?
class Script
{
public:
Script() { /* ... */ }
template<typename TFunction>
void AddHandler(const char *handlerName, TFunction &&function)
{
_handlerMap[handlerName] = std::move(function);
}
void Handle(const char *handlerName, ...)
{
_handlerMap[handlerName](...);
}
private:
typedef std::map<std::string, std::function<void()>> HandlerMapType;
HandlerMapType _handlerMap;
};
//Handler functions
handlerOne() { std::cerr << "One"; }
handlerTwo(std::string a1, int a2) { std::cerr << "Two"; }
handlerThree(bool a1) { std::cerr << "Three"; }
int main(int argc, char **argv)
{
Script script;
script.AddHandler("One", std::bind(&handlerOne));
script.AddHandler("Two", std::bind(&handlerTwo));
script.AddHandler("Three", std::bind(&handlerThree));
script.Handle("One");
script.Handle("Two, "string", 96);
script.Handle("Three", true);
script.Handle("Three", "what should happen here?"); //String passed instead of bool
}
Let me prefix by saying that this is not a trivial thing to do in C++. And I will go as far to say that you should consider whether this is really something you need in your use case. In your example, you are asking for genericism that you can't really use. You will in any case need to know the signature of the function you are calling to call it properly; in that case what purpose is served by putting them in a container?
Generally, you'd do something like this if you are writing a middle layer of code. In your example, this would be equivalent to writing code that enables another user to call Handle. A common concrete example of this is to write a factory where objects in the factory may be instantiated using different arguments. However, it can't really be "different" arguments, at least not without some crazy casting. The solution is to make all the functions take the same argument, but make the argument a dynamic type that can store whatever arguments you want:
using argument_type = std::unordered_map<std::string, boost::any>;
void print(const argument_type & arg) {
auto to_print = boost::any_cast<std::string>(arg["to_print"]);
std::cerr << to_print << std::endl;
}
void print_none(const argument_type & arg) {
std::cerr << "none" << std::endl;
}
using my_func_t = std::function<void(const argument_type &)>;
std::vector<my_func_t> v;
v.emplace_back(print);
v.emplace_back(print_none);
// create some argument_types, feed them to f.
The above is not code that has been tested, nor with a working main, but I think this should give you a sense of how you could accomplish what you want.
edit: I thought about it a bit more, and I decided to elaborate a bit more on the "crazy casting" way. I suppose it's not really more crazy, but I strongly prefer what I showed above. The alternative is to completely type erase the functions themselves, and pass the arguments using a variadic template.
void print(std::string to_print) {
std::cerr << to_print << std::endl;
}
void print_none() {
std::cerr << "none" << std::endl;
}
std::vector<boost::any> v;
v.emplace_back(std::function<void(std::string)>(print));
v.emplace_back(std::function<void(void)>(print_none));
template <typename ... Args>
void call(const std::vector & funcs, int index, Args... args) {
auto f = boost::any_cast<std::function<void(Args...)>>(funcs[index]);
f(std::forward<Args>(args)...);
}
// unsure if this will actually work
call(f, 0, std::string("hello"));
The code above is very fragile though, because the types you pass to call will be deduced against, and then the cast will try to cast to a std::function that matches that signature. That exact signature. I don't have a lot of confidence that this will work out; if it's a reference, vs value, vs rvalue, etc. Casting back to a different std::function than what you put in is undefined behavior.
In summary, I'd either try to avoid needing to do this entirely, or go with the first solution. It's much less fragile, and it's better to be upfront about the fact that you are erasing the signatures of these functions.

functor: wrapping std::function in a class

Say I am writing a library that should provide some default computing (function), but enables the user to provide his own, at compile-time.
For instance, say the library provides a function that returns his argument times 3, but the user can provide his own function.
Consider the following program (to be seen as a MWE):
float myFunction( float v ) // the function the user needs
{
return v*2;
}
int main()
{
FuncWrapper f;
cout << "default: " << f(2) << endl; // should print "6"
f.AssignFunction( myFunction );
cout << "now is: " << f(2) << endl; // should print "4"
}
So I have build a functor FuncWrapper that wraps a std::function, as proposed also here:
struct FuncWrapper
{
std::function<float(float)> foo; // the function used
float def( float v ) // the default behaviour member function definition
{
return v*3;
}
float operator()( float v ) // call of function
{
return foo(v);
}
void AssignFunction( float (*uf)(float) ) { foo = uf; }
// constructor: initializes to default function
FuncWrapper() : foo(&FuncWrapper::def) {}
};
On my machine (gcc 4.6.3) with -std=c++0x, I get non human-readable error messages, as stated in this other answer. For conveniency, the code is runnable here. Seems to be gcc 4.8, and it doesn't like the constructor (among other errors...):
main.cpp: In constructor 'FuncWrapper::FuncWrapper()':
main.cpp:27:64: error: no matching function for call to 'std::function<float(float)>::function(float (FuncWrapper::*)(float))'
Why is this assignment illegal ? I have searched for this topic, maybe wrong keyword, but didn't find anything relevant.
Any clue? Or a simpler solution, maybe without std::function but with a function pointer?
In your example code, you try to assign your member function to a std::function with signature float(float). These two are not compatible, since the member function has a different calling convention: it requires a this argument.
Make your default function static to avoid this.

Passing anonymous function as only parameter to another function (C++)

I've read posts/articles about lambdas, function pointers, anonymous functions in general and other related things but nothing I've seen (I think) has hit on exactly what I'm looking to do.
It seems like accomplishing this should be pretty simple, but say I have a function containing things I always want to do when called, but each time I call it I want it to run a function I describe (and only need to use once) in the argument (this anonymous function being the only argument).
Assuming this function which accepts my anonymous function as its argument is in main.cpp so it's called from main is it possible to implement this in a simple way?
Basically I'm trying to figure out the syntax in C++ for going from this:
// Some function with partially duplicated code
void OriginalA()
{
DoThingsA();
// unique code
DoThingsB();
}
// Another function with partially duplicated code
void OriginalB()
{
DoThingsA();
// unique code
DoThingsB();
}
To this:
// Encapsulate shared functionality
// <param name="action">User defined action</param>
void UniqueWrapper(Action action)
{
DoThingsA();
action();
DoThingsB();
}
// New implmentation of A
void NewA()
{
UniqueWrapper(() =>
{
// unique code
});
}
// New implementation of B
void NewB()
{
UniqueWrapper(() =>
{
// unique code
});
}
Which I found as #1 here: http://www.wildbunny.co.uk/blog/2012/11/01/10-steps-to-becoming-a-better-programmer/
But a setup like this where literally all you would have to do for the call is:
theFunctionName(() => { /*unique things to do*/ });
If this ^^ is legal calling syntax then I'm just not sure how the parameter looks in the definition of theFunctionName, clearly it isn't (Action action) like in the example above.
Replace the Action argument with:
template<typename Function>
void UniqueWrapper(Function action) {
DoThingsA();
action(); // call the passed in function
DoThingsB();
};
Call it like this:
void NewA() {
UniqueWrapper([]() {});
// ^^^^^^^
// C++11 lambda syntax
}
Instead of a lambda you can also use function pointers, member functions (using std::mem_fn), or functors. Every kind of callable object will work.
There are multiple ways to do this, but not all will work on all platforms (e.g. because they'd require C++11 features (lambdas).
The more classic approach would be something like this (without an anonymous function):
#include <iostream>
typedef void(*Action)();
void UniqueWrapper(Action action) {
std::cout << "Generic Code 1" << std::endl;
action();
std::cout << "Generic Code 2" << std::endl;
}
void CustomAction(void) {
std::cout << "Custom Code" << std::endl;
}
int main(int argc, char **argv) {
UniqueWrapper(&CustomAction);
return 0;
}
Of course you could use some macro shenanigans to make this more "dynamic".
Once you accept C++11 code as well (which is required to have lambdas as explained), you can do something like this:
#include <iostream>
typedef void(*Action)();
void UniqueWrapper(Action action) {
std::cout << "Generic Code 1" << std::endl;
action();
std::cout << "Generic Code 2" << std::endl;
}
int main(int argc, char **argv) {
UniqueWrapper([](){
std::cout << "Custom Code" << std::endl;
});
return 0;
}
Of course, there's room for more changes, for example you could use std::function rather than a function pointer.

Duplicating C/C++ functions at compile time

If I have a function A(), I am interested in finding a convenient method to create a function B() that has the exact same functionality as A(), differing only in name. The new function would be for a one-time use. The intent is to differentiate between calls to the same function in a somewhat primitive sampling profiler, and the duplicated function would only be used in this context. That is, it would never touch production code and only be used for tinkering.
First guess would be a macro that declares a function named B and creates an inlined call to A() inside of it. The problem here is that I'm not aware of a method in GCC to force an arbitrary function call to inline; it seems all inlining options are for function declarations rather than calls.
There may be some esoteric way to do it with templates, or possibly by tricking the compiler into inlining. I'm not sure it's possible. Any thoughts? Unfortunately the new C++ standard is not available, if it would make a difference.
Using templates
template<int x>
void A()
{
// ..
}
int main()
{
A<0>();
A<1>();
return 0;
}
Update
The compiler can be too smart and create only one body for A<0> and A<1>. At least Visual C++ 2010 does it in Release mode. To prevent it, just use the template parameter inside the function template body in logs or asserts. For example,
#include <iostream>
template<int x>
void A()
{
::std::cout << x << std::endl;
// ..
}
int main()
{
A<0>();
A<1>();
auto v0 = A<0>;
auto v1 = A<1>;
::std::cout << v0 << std::endl;
::std::cout << v1 << std::endl;
::std::cout << (v0 == v1) << std::endl;
return 0;
}
This works using templates:
#include <iostream>
template<typename T>
void foo() {
static int x = 0;
std::cout << &x << std::endl;
}
int main(int argc, char **argv) {
foo<int>();
foo<float>();
return 0;
}
If you execute that, you'll see two different values printed, reflecting the compiler generated code for both calls, even though the template parameter is unused. nm on the object file confirms this.
If this is a one-time debug hack, then why not:
#define A_CONTENT \
... // whatever
void A()
{
A_CONTENT
}
void B()
{
A_CONTENT
}
...
A(); // Call to A
B(); // Call to B
Macros are generally grim, but we're not talking about production code here, so who cares?
Having been down this road myself, the short answer is that even if you get the compiler to emit two identical duplicates of a function, the optimizing linker will notice that they're identical and fold them back together into one implementation. (And if you've turned off optimization in the linker, then your profile isn't valid anwyay).
In the context of a sampling profiler, I've found the easier approach is to make two tiny wrappers for the function instead:
void Func() { .... }
_declspec(noinline)
void A_Func( return Func(); }
void B_Func( return Func(); }
void C_Func( return Func(); }
Then when your profiler samples the callstack, you'll be able to differentiate between the different callsites of this function in a very straightforward way..
You could always define a macro, for example in Chromium we do the following to reuse code:
#define CHROMEG_CALLBACK_1(CLASS, RETURN, METHOD, SENDER, ARG1) \
static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, \
gpointer userdata) { \
return reinterpret_cast<CLASS*>(userdata)->METHOD(sender, one); \
} \
\
virtual RETURN METHOD(SENDER, ARG1);
And we call them like:
CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnExposeEvent, GdkEventExpose*);
CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnButtonPressed, GdkEventButton*);
You can do something similar to do what you wanted. The above example shows us using two different implementations but with one common code base. For GTK callbacks.
It's a little unclear what you're really trying to do, but a really ugly solution would be to declare the body of A as a macro and then you can "inline" this macro within whatever functions you like.
Also, macros are evil. Never use them unless you really have to.
Why do you care so much about inlining it? If you create a wrapper function, there is a pretty good chance the compiler will inline it anyway. At the very least, you're unlikely to get a function frame constructed.
C++11 also lets you do this:
void A() {
...
}
...
auto B = [] () -> void { A(); };
You can now use B syntactically as though it was a function wrapping A.