Use C++11 lambdas as callbacks in GObject library - c++11

C++11 lambdas that does not capture anything can be stored in a function pointer. One just need to ensure that lambda accepts and returns the same parameters as the function pointer.
In GObject library all callbacks has type void(*GCallback) (void). This definition does not anyhow affect signature of the callback though:
The type used for callback functions in structure definitions and
function signatures. This doesn't mean that all callback functions
must take no parameters and return void. The required signature of a
callback function is determined by the context in which is used (e.g.
the signal to which it is connected). Use G_CALLBACK() to cast the
callback function to a GCallback.
In other words, one can pass function like this:
int my_function(int a, char b) {}
by casting its type (that's what G_CALLBACK do):
do_something(G_CALLBACK(my_function));
Unfortunately typecasting does not work with C++11 lambdas:
do_something(G_CALLBACK([](int a, char b) -> int {...});
// Cannot cast from type lambda to pointer type GCallback
Is it possible to use C++ lambdas of arbitrary type in place of GCallback?
UPDATE
Just to clarify, I know that lambda can be casted to a function pointer if their signatures match. My question is in another dimension.
The ISO C standard guarantees that function can be casted forth and back without loosing any precision. In other words one the following expression is valid:
int f(int a){...}
void (*void_f)() = (void (*)())f;
int (*restored_f)(int) = (int (*)(int))void_f;
restored_f(10);
My question is whether the following expression is also valid according to C++11:
int (*f)(int) = [](int a) -> int {};
void (*void_f)() = (void (*)())f;
int (*restored_f)(int) = (int (*)(int))void_f;
restored_f(10);

The following code compiles and works for me (MSVC 2013):
auto lambdaFunc = [](int a, char b) -> int { return 0; };
typedef int (*LambdaType)(int, char);
GCallback fnTest1 = G_CALLBACK((LambdaType)lambdaFunc);
GCallback fnTest2 = G_CALLBACK((LambdaType) [](int a, char b) -> int { return 0; });
do_something(fnTest1);
do_something(fnTest2);
do_something(G_CALLBACK((LambdaType)lambdaFunc));

Lambdas without a capture are implicitly convertible to a pointer to a function by the standard. Though not all compilers support this feature at the moment (https://stackoverflow.com/a/2935230/261217).
Then you can explicitly cast a function pointer to GCallback.

Related

Can ‘auto’ be used in a function declaration?

Background:
I found this handy random number generator and wanted to make a header file for it:
http://www.cplusplus.com/reference/random/
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(1,6);
auto dice = std::bind ( distribution, generator );
int wisdom = dice()+dice()+dice();
However, in C++11, a function declaration with return type ‘auto’ requires a trailing return type so the compiler can decide what the type is.
E.g.:
auto foo(int a, int b) -> decltype(a*b);
Problem:
It appears like my header would need to be almost as long as the function itself to determine the type:
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(1,6);
auto roll() -> decltype(distribution(generator));
Question:
Is there a way around determining the full return type for a function declaration (in a header) that uses the ‘auto’ type?
If not, what should my dice() header look like?
Since you use int as the template type for std::uniform_int_distribution, the return type of distribution(generator) is int. Unless the real code is templated as well, then the return type could be hard-coded to int.
And if the real code is templated then you can use the result_type member of std::uniform_int_distribution:
template<typename T>
typename std::uniform_int_distribution<T>::result_type roll();
Or simply the template type itself:
template<typename T>
T roll();

using stable_sort and passing an object as the custom comparison operator

This is part of an assignment, I am stuck at this instruction:
Sort your randomly generated pool of schedules.
Use std::stable_sort,
passing in an object of type schedule_compare as the custom comparison
operator.
UPDATE: I was checking cppreference stable_srot(), see method definition below:
void stable_sort ( RandomAccessIterator first, RandomAccessIterator
last,Compare comp );
, and it seems from what I understood is that you can only pass functions to the last argument (Compare comp) of the stable_sort() i.e:
However, in the instructions, it says that you need to pass an object of type schedule_compare. How is this possible ?
This is my code below:
struct schedule_compare
{
explicit schedule_compare(runtime_matrix const& m)
: matrix_{m} { }
bool operator()(schedule const& obj1, schedule const& obj2) {
if (obj1.score > obj2.score)
return true;
else
return false;
}
private:
runtime_matrix const& matrix_;
};
auto populate_gene_pool(runtime_matrix const& matrix,
size_t const pool_size, random_generator& gen)
{
std::vector<schedule> v_schedule;
v_schedule.reserve(pool_size);
std::uniform_int_distribution<size_t> dis(0, matrix.machines() - 1);
// 4. Sort your randomly generated pool of schedules. Use
// std::stable_sort, passing in an object of type
// schedule_compare as the custom comparison operator.
std::stable_sort(begin(v_schedule), end(v_schedule), ???)
return; v_schedule;
}
For algorithm functions that accepts a "function" (like std::stable_sort) you can pass anything that can be called as a function.
For example a pointer to a global, namespace or static member function. Or you can pass a function-like object instance (i.e. an instance of a class that has a function call operator), also known as a functor object.
This is simply done by creating a temporary object, and passing it to the std::stable_sort (in your case):
std::stable_sort(begin(v_schedule), end(v_schedule), schedule_compare(matrix));
Since the schedule_compare structure have a function call operator (the operator() member function) it can generally be treated like any other function, including being "called".

Why does initialization of int by parenthesis inside class give error? [duplicate]

For example, I cannot write this:
class A
{
vector<int> v(12, 1);
};
I can only write this:
class A
{
vector<int> v1{ 12, 1 };
vector<int> v2 = vector<int>(12, 1);
};
Why is there a difference between these two declaration syntaxes?
The rationale behind this choice is explicitly mentioned in the related proposal for non static data member initializers :
An issue raised in Kona regarding scope of identifiers:
During discussion in the Core Working Group at the September ’07 meeting in Kona, a question arose about the scope of identifiers in the initializer. Do we want to allow class scope with the possibility of forward lookup; or do we want to require that the initializers be well-defined at the point that they’re parsed?
What’s desired:
The motivation for class-scope lookup is that we’d like to be able to put anything in a non-static data member’s initializer that we could put in a mem-initializer without significantly changing the semantics (modulo direct initialization vs. copy initialization):
int x();
struct S {
int i;
S() : i(x()) {} // currently well-formed, uses S::x()
// ...
static int x();
};
struct T {
int i = x(); // should use T::x(), ::x() would be a surprise
// ...
static int x();
};
Problem 1:
Unfortunately, this makes initializers of the “( expression-list )” form ambiguous at the time that the declaration is being parsed:
struct S {
int i(x); // data member with initializer
// ...
static int x;
};
struct T {
int i(x); // member function declaration
// ...
typedef int x;
};
One possible solution is to rely on the existing rule that, if a declaration could be an object or a function, then it’s a function:
struct S {
int i(j); // ill-formed...parsed as a member function,
// type j looked up but not found
// ...
static int j;
};
A similar solution would be to apply another existing rule, currently used only in templates, that if T could be a type or something else, then it’s something else; and we can use “typename” if we really mean a type:
struct S {
int i(x); // unabmiguously a data member
int j(typename y); // unabmiguously a member function
};
Both of those solutions introduce subtleties that are likely to be misunderstood by many users (as evidenced by the many questions on comp.lang.c++ about why “int i();” at block scope doesn’t declare a default-initialized int).
The solution proposed in this paper is to allow only initializers of the “= initializer-clause” and “{ initializer-list }” forms. That solves the ambiguity problem in most cases, for example:
HashingFunction hash_algorithm{"MD5"};
Here, we could not use the = form because HasningFunction’s constructor is explicit.
In especially tricky cases, a type might have to be mentioned twice. Consider:
vector<int> x = 3; // error: the constructor taking an int is explicit
vector<int> x(3); // three elements default-initialized
vector<int> x{3}; // one element with the value 3
In that case, we have to chose between the two alternatives by using the appropriate notation:
vector<int> x = vector<int>(3); // rather than vector<int> x(3);
vector<int> x{3}; // one element with the value 3
Problem 2:
Another issue is that, because we propose no change to the rules for initializing static data members, adding the static keyword could make a well-formed initializer ill-formed:
struct S {
const int i = f(); // well-formed with forward lookup
static const int j = f(); // always ill-formed for statics
// ...
constexpr static int f() { return 0; }
};
Problem 3:
A third issue is that class-scope lookup could turn a compile-time error into a run-time error:
struct S {
int i = j; // ill-formed without forward lookup, undefined behavior with
int j = 3;
};
(Unless caught by the compiler, i might be intialized with the undefined value of j.)
The proposal:
CWG had a 6-to-3 straw poll in Kona in favor of class-scope lookup; and that is what this paper proposes, with initializers for non-static data members limited to the “= initializer-clause” and “{ initializer-list }” forms.
We believe:
Problem 1: This problem does not occur as we don’t propose the () notation. The = and {} initializer notations do not suffer from this problem.
Problem 2: adding the static keyword makes a number of differences, this being the least of them.
Problem 3: this is not a new problem, but is the same order-of-initialization problem that already exists with constructor initializers.
One possible reason is that allowing parentheses would lead us back to the most vexing parse in no time. Consider the two types below:
struct foo {};
struct bar
{
bar(foo const&) {}
};
Now, you have a data member of type bar that you want to initialize, so you define it as
struct A
{
bar B(foo());
};
But what you've done above is declare a function named B that returns a bar object by value, and takes a single argument that's a function having the signature foo() (returns a foo and doesn't take any arguments).
Judging by the number and frequency of questions asked on StackOverflow that deal with this issue, this is something most C++ programmers find surprising and unintuitive. Adding the new brace-or-equal-initializer syntax was a chance to avoid this ambiguity and start with a clean slate, which is likely the reason the C++ committee chose to do so.
bar B{foo{}};
bar B = foo();
Both lines above declare an object named B of type bar, as expected.
Aside from the guesswork above, I'd like to point out that you're doing two vastly different things in your example above.
vector<int> v1{ 12, 1 };
vector<int> v2 = vector<int>(12, 1);
The first line initializes v1 to a vector that contains two elements, 12 and 1. The second creates a vector v2 that contains 12 elements, each initialized to 1.
Be careful of this rule - if a type defines a constructor that takes an initializer_list<T>, then that constructor is always considered first when the initializer for the type is a braced-init-list. The other constructors will be considered only if the one taking the initializer_list is not viable.

casting void* to std::function

I have an issue. I'm trying to convert a void* to std::function.
This is just a simple example, any suggestions will be appreciated
#.h file
class Example {
public:
Example();
int foo(void* hi);
int fooFunc(std::function<int(int, int)> const& arg, int x, int y) {
foo(arg.target<void*>(), x, y);
return 2;
}
};
#.cpp file
Example::Example() {
}
int Example::foo(void * func, int x, int y)
{
//cast back to std::function
func(x, y);
std::cout << "running in foo: " << a << "\n";
return a;
}
Every casting i tried did not work.
I know i can send a std::function in this example, but it's for something bigger and i'm working on an example to make it work here.
The whole meaning of void*, is for sometimes to use it, in these situations, when you don't know what you will receive, and then cast it to the specific usage you need.
Thanks!
You can't.
You can cast a data pointer to void* and then back to the same pointer type you have started with. std::function is not a pointer type, so the cast is statically invalid, and it's not the same thing you have started with. You have started with a .target of type void(*)() but it's not a data pointer, it's a function pointer, so casting it to void* and back is implementation-defined.
You can:
Ignore the issue and cast to void(*)() anyway. Will work on most (but not all) platforms.
Use void(*)() instead of void* as a universal function pointer (you can cast it to other function types).
Use whatever tools C++ offers to avoid the cast altogether.

How to decorate a function in C++

I would like to achieve the following
#include <iostream>
unsigned foo(int i) {return i;};
unsigned bar(unsigned(*p)()) {/*Do important work*/return p();};
int main(void){
int integer = 42;
auto lambda = [integer] () -> unsigned {return foo(integer);};
unsigned number = bar(lambda);
std::cout << number << std::endl;
}
That is, bar is expecting a pointer to function with no arguments and returning unsigned. I can easily write a wrapper unsigned baz() {return foo(42);};and pass that one to bar(), but this has two drawbacks
it's a separate function, while I would prefer to construct the wrapper inline
I have to write a new wrapper for each expected value of `integer.
The idea is that bar() is doing some work, in the process invoking the function, that was passed to it. I have a suitable function, but it has an extra argument. That extra argument, however, is known at the point of passing the function to bar().
Is there a way to pull this off, or should I forget this approach and use templates? I have control over changing the interface (e.g. change the function pointer argument to std::function).`

Resources