std::function, template parameter T(X) - c++11

I'm wondering if anyone can please explain how, given types T and X, std::function takes T(X) as a template parameter.
int(double) looks like the usual cast from double to int, so how is std::function parsing it as distinct types?
I did search but didn't find anything that specifically addresses this question. Thanks!

It can use partial template specialization. Look at this:
template <typename T>
class Func;
template <typename R, typename... Args>
class Func<R(Args...)>
{
public:
Func(R(*fptr)(Args...)) {/*do something with fptr*/}
};
This class takes a single template parameter. But unless it matches R(Args...) (i.e. a function type returning R and taking zero or more args), there wont be a definition for the class.
int main() { Func<int> f; }
// error: aggregate 'Func<int> f' has incomplete type and cannot be defined
.
int func(double a) { return a+2; }
int main() { Func<int(double)> f = func; }
// ok
The specialization can now operate on R and Args to do its magic.
Note that int(double) is a function type. Since you cannot create raw function objects, you don't usually see this syntax outside the template world. If T is int(double) then T* is a function pointer just like int(*)(double).

Related

Is there a programming language where functions can be declared with different type arguments?

I've been daydreaming about this language where you can define different functions with the same name but whose arguments are of different type (or length).
Here's a naive example, assuming a C-like syntax.
struct vect {
int x;
int y;
};
struct guy {
struct vect pos;
char *name;
};
struct guy new_guy(vect v, char *name) {
struct guy g;
g.pos = v;
g.name = name;
return g;
}
struct guy new_guy(int x, int y, char *name) {
struct vect v;
v.x = x;
v.y = y;
return new_guy(v, name);
}
int get_x(struct vect v) {
return v.x;
}
int get_x(struct guy g) {
return g.pos.x;
}
The point would be in avoiding having long names like: get_vect_x and get_guy_x, etc. The compiler knows what types we are using to call a function so it shouldn't be a problem to figure out which definition to use.
There could also be different definitions for different number of arguments.
From Wiki:
In some programming languages, function overloading or method overloading is the ability to create multiple functions of the same name with
different implementations. Calls to an overloaded function will run a specific implementation of that function appropriate to the context of the call,
allowing one function call to perform different tasks depending on context.
wiki link giving definition of function overloading
Java is capable of this, which would lead me to wonder if C++ is (much less experienced with it than Java). Declaring methods of the same name with different parameters or similar parameters different types is supported, even with constructors. This is likely easily implemented in Java because it's a statically typed language. A quick way to check if this is possible is to look at the docs of a particular language's standard libraries for constructors that take different combinations of parameters.

Why sizeof of a structure or union in C need a variable?

The code below could not be compiled(GCC). It said that the person and u_type are undeclared. If I use a variable in sizeof(), it is OK. So why need a variable in sizeof(). The GNU C Reference Manual said that sizeof operator can be used with both type and expression.
Thanks,
struct person {
int age;
char *name;
};
union u_type {
int t_int;
double t_double;
};
int main(void) {
printf("size of person is %d\n", sizeof(person));
printf("size of u_type is %d\n", sizeof(u_type));
return 0;
}
There is nothing in your program called person or u_type. Sure you have struct person and union u_type but there are no typedefs to let you just use person and u_type
Try sizeof(struct person)
To answer the questions in the comments:
struct person { ... }; Gives you a type: struct person- where person is a tag. You need to use struct person to use the type. In this case sizeof(struct person).
struct { ... } person; Gives you a variable called person that is a struct (but you can't reuse the type). In this case sizeof(person)
The most common use is typedef struct { ... } Person which gives you a type Person - much like the first case, but you can use Person instead of struct person. In this case sizeof(Person)
This is because sizeof operator needs something for which it can tell size of.
If it is left empty, it would have nothing to review and generate an answer, but because you have used it in the program by passing no arguments, it will give an error because sizeof empty is kind of vague if you understand.

Deduce return type of a function template from argument types (not from arguments)

I am aware of the very straightforward usage of decltype, as in
template<typename T, typename F>
auto myfunc(T elem, F func) -> decltype(func(elem))
{
return func(elem);
}
I would like to know whether return type of a function can be deduced without reference to the function arguments, but instead to the argument type, i.e. something akin to decltype(func, T)?
I understand that in this case one is a type and the other is an object, but what I'm trying to do seems to be very natural. Yet I failed to find a simple way of expressing what I want. Any help?
Thank you.
This is exactly what std::declval is for:
template<typename T, typename F>
auto myfunc(T elem, F func) -> decltype(func(std::declval<T>()))
{
return func(elem);
}
But since you do have an object of that type already, why bother?

Weird substitution failure with C++11 variadic template

I'm having a hard time figuring out what causes the substitution failure in this example code:
bool f(int a, int b, float c)
{
printf("%d %d %f", a, b, c);
return true;
}
template <typename ...Params>
void call1(Params... params, std::function<bool(Params...)> func)
{
func(params...);
}
template <typename ...Params>
void call2(std::function<bool(Params...)> func)
{
}
Somewhere in main:
call1<int, int, float>(3, 4, 5.5, f); // Ok.
call2<int, int, float>(f); // Substitution failure.
The compiler says:
template argument deduction/substitution failed: mismatched types 'std::function<bool(Params ...)>' and 'bool (*)(int, int, float)'
call2<int, int, float>(f);
^
What baffles me is that call1 works while call2 doesn't.
Any tips? =)
First: You can specify less arguments than what you use and let the compiler deduce the rest:
template <typename ...Params>
void func1(Params... params);
func1<int, int>(1, 2, 3); // calls func1<int, int, int>
This means Params is still open for adding extra types when you call it. But if you take the function address, it becomes defined and closed:
auto x = func1<int, int>;
x(1, 2, 3); // not possible
When you call your call1 function directly:
template <typename... Params>
void call1(Params... params, std::function<bool(Params...)> func);
call1<int, int, int>(1, 2, 3, f);
call1<int>(1, 2, 3, f); // same as before
call1(1, 2, 3, f); // same as before
The compiler is able to deduce that you have exactly 3 ints because you just sent him 3 ints. This way the last parameter must be std::function<bool(int, int, int)> because we fully deduced what Params... means and there's no space for more types.
Now the problematic case:
template <typename... Params>
void call2(std::function<bool(Params...)> func);
call2<int, int, int>(f);
Here you informed the compiler that the first 3 elements of Params are all ints. Params = {int, int, int, ...}. Note that it is still open for adding something else if deduction tells so. Replacing we have: std::function<bool(int, int, int, ...)> func. The compiler can't possibly know what this incomplete type means unless you explicitly pass a std:function (exact match). It doesn't know yet it can have a constructor taking the function pointer you provided, so there's a mismatch. Now the compiler does not have enough data to decide if it need more types into Params or not. Failure.
But note this interesting case:
auto x = call2<int, int, int>;
x(f); // x is exactly void(*)(std::function<bool(int, int, int)>). No doubts.
Here the you force Params to be complete. There's no deduction to evaluate. Although ugly, this also works:
(&call2<int, int, int>)(f);
The compiler can't deduce the type with your current code (even though the function pointer is implicitly convertible to a std::function). You could create a traits class to help deduce the correct type.
template <typename... Params>
struct func_traits {
using func_type = std::function<bool(Params...)>;
};
template <typename ...Params>
void call2(typename func_traits<Params...>::func_type func) {}
The type of the expression f is a pointer to function, i.e. bool (*)(int, int, float). Yet the explicit instantiation of call2 template has type void foo (std::function<bool (int, int, float)> ), i.e. the parameter type is different, hence the mismatch.
Workaround:
auto x = call2<int, int, float>;
x(f);
taking advantage of the possibility to construct a std::function from a function pointer.

modinfo() equivalent INSIDE kernel?

I have two modules A, B. A has a function f() that is globally acessible, i.e. the f() symbol is exported. B may want to call f() occasionally. But B should only call f() if module A is loaded. What is the best way for B to tell if A is loaded?
Part b to this question is there is a way to check if f() is exported?
I'm not sure which method is more effecient.
I assume you load module B first, then optionally module A. My strategy would be to have A register a set of functions with B when A first initializes. B keeps a statically allocated function pointer (or a pointer to a struct full of function pointers) and provides exported functions to register and unregisters a handler. When A loads, it registers its function (or struct of functions) with B. When A unloads, it unregisters its functions.
It might go something like this:
B.h
typedef int (*foo_t)(int);
int B_register_foo(foo_t);
int B_unregister_foo(foo_t);
B.c
static foo_t foo = NULL;
int B_register_foo(foo_t f) {
if (!foo) {
foo = f;
return 0;
}
return -EFOO;
}
void B_unregister_foo(foo_t f) {
if (foo == f)
foo = NULL;
}
EXPORT_SYMBOL(B_register_foo);
EXPORT_SYMBOL(B_unregister_foo);
void B_maybe_call_foo(int arg) {
return (foo) ? foo(arg) : 0;
}
A.c
static int A_foo(int arg);
static int __init init_A(void) {
if (B_register_foo(A_foo))
return -EFOO;
return 0;
}
static void __exit exit_A(void) {
B_unregister_foo(A_foo);
}
If B uses at least one of A's symbols, then by the time B is loaded, a module providing the required symbol(s) (in other words, a module like A) is also already loaded.
Part b to this question is there is a way to check if f() is exported?
If the symbol were not available, you would not be able to load the module (B) requesting it.

Resources