C++ template <R(*)(T)> meaning - c++

What does the following template do in C++?
template <class R, class T>
struct my_type<R(*)(T)> { typedef T type; };
Specifically, what does the * stand for in this context?

In this context it makes the template specialization refer to a pointer to a function, which is declared to accept a single argument of type T, and return a value of type R. The specialization extracts the argument type and makes it available as a typedef.
Example (demo):
#include <iostream>
#include <type_traits>
int foo(float);
template <typename T>
struct my_type;
template <class R, class T>
struct my_type<R(*)(T)> { typedef T type; };
int main() {
std::cout
<< std::is_same<
float,
typename my_type<decltype(&foo)>::type
>::value
<< "\n";
return 0;
}
This outputs 1 because float and typename my_type<decltype(&foo)>::type both refer to the same type -- decltype(&foo) is the type int (*)(float), which matches the specialization R(*)(T).

Great answer above by cdhowie, but I feel it's more explaining what template specialization does, and not so much answers the specific question: what does the * stand for in R(*)(T).
For that, we need to take a look at how we specify types in C++'s type system. Don't be offended if you already know most or all this, but I think I can best explain it if I just start with the basics. If not you, perhaps someone else can learn from this (I myself was pretty confused by C(++)'s type system, coming from Pascal :)). If you just want the answer, it's the last sentence of this post.
Say we want to declare a variable named foo that is of type int.
int foo;
Well, that's easy enough. Now, let's change that to be an array of 3 ints:
int foo[3];
It's important to realize what we've done here. You might be tempted to think that array specifiers simply go last, but that's not the case. Because, to declare an array of something, we need to add brackets right after the identifier that names our variable, or foo in this case. This becomes clear when you want to extend this declaration to be an array of 2 × int[3]:
int foo[2][3];
So, by substituting foo with foo[2] in the declaration int foo[3], we get to int foo[2][3]. And that's why foo is an array of 2 × [array of 3 × int]. This becomes more apparent when we add parentheses (which we are in fact allowed to do):
int foo; // [int]
int (foo[3]); // array of 3×[int]
int ((foo[2])[3]); // array of 2×[array of 3×[int]]
C++ uses a similar system for pointers. To declare a pointer to something, prefix the identifier with a *.
int foo; // [int]
int (*foo); // pointer to [int] (same as: int *foo)
int (*(*foo)); // pointer to [pointer to [int]] (same as: int **foo)
So, we've substituted foo with (*foo) on every next line.
This is where things get interesting. We need to prefix the identifier with a * for a pointer, and postfix it with [] for an array, but then, what does int *foo[3] mean? As it turns out, int *foo[3] is parsed as int *(foo[3]). So, it is an array of 3 × [pointer to int]. To get a pointer to [array of 3 × int], we need to do: int (*foo)[3]
int *(foo[3]); // array of 3×[pointer to [int]] (same as: int *foo[3])
int (*foo)[3]; // pointer to [array of 3×[int]]
Now, to answer your question, we need to look at function declarations. This is actually similar to arrays. To declare a function, add parentheses and a list of arguments right after the identifier:
int foo; // [int]
int (foo()); // function returning [int] (same as: int foo())
Now we can also apply above rules:
int foo; // [int]
int (foo()); // function returning [int] (same as: int foo())
int ((*foo)()); // pointer to [function returning [int]] (same as: int (*foo)())
int ((*(foo[2]))()); // array of 2×[pointer to [function returning [int]]] (same as: int (*foo[2])())
To name a type without the identifier, simply erase the identifier. So the type of the third foo in above example is simply int(*)(). Note that the parentheses here are mandatory. If it were int*(), it would be a function returning [pointer to [int]].
Tip: to figure out the type of something, use a bottom-up approach, starting at the identifier (or where the identifier would be), working outward, using the following annotations: * stands for "pointer to...", [] for "array of..." and (x) for "function taking (x) and returning...". As a rule of thumb: if there are no parentheses, the right hand side goes before the left hand side.
Now we can answers your question: the * in R(*)(T) stands for: a pointer to a function that takes a T as argument and returns an R.

Related

Declaration of a function pointer's typedef in C++

I understand that similar questions with answers have been asked before. I already understand the concept of a function pointer and the meaning of its declaration. Following is my sample code of a function's pointer, where I assign the function pointer fp_GetBiggerElement to point to the function GetBiggerElement
#include <iostream>
typedef int (*fp_GetBiggerElement) (int, int);
// ^ ^ ^
// return type type name arguments
using namespace std;
int GetBiggerElement(int arg1, int arg2)
{
int bigger = arg1 > arg2 ? arg1 : arg2;
return bigger;
}
int main()
{
fp_GetBiggerElement funcPtr = GetBiggerElement;
int valueReturned = funcPtr(10, 20);
cout << valueReturned << endl;
return 0;
}
What I understand is, typedef means to assing a new definition for a type. Usually, the typedef statement needs two-parts(or say two-arguments)
first part is the type which needs a new alias
second part is a new alias name
typedef unsigned int UnsignedInt;
// ^ ^
// (original type) (Alias)
for example, in the code above, the first part is unsigned int and the second part is UnsignedInt
typedef char * CharPtr;
// ^ ^
// (original type) (Alias)
similarly, in the second example above, the first part is char* and the second part is CharPtr
QUESTION: I am confused with the FORMAT of the typedef statement for a function pointer. In the statement typedef int(*fp_GetBiggerElement)(int, int);, the typical two-arguments format for typedef is not followed then, how is it working?
UPDATE: I am aware that C++11 offers another way of declaring function pointer i.e. (by using statment). In this question, I am only interested to understand the syntax of typedef statement for a fucntion pointer.
I think the best idea to think about typedef syntax is like declaring variable of type you want to typedef. For example:
char *CharPtr;// declare CharPtr to be variable of type char*
typedef char *CharPtr_t;// declare CharPtr_t to be alias of type char*
Similarly with function pointers:
int (*fp) (int, int);// declare fp as pointer to int(int, int)
typedef int (*fp_t)(int, int);// declare fp_t to be alias of pointer to int(int, int)
Btw, in C++11 and further you get not-so-confusing (and more powerful) alternative to typedef - using. You should be using (pun intended) it instead. Just look:
using fp = int (*)(int, int);// declare fp_t to be alias of pointer to int(int, int)
typedef uses the same syntax as a variable declaration, but declares a type name rather than a variable name.
The parts are "intermingled" in a somewhat peculiar (some would call it "wtf?") way - a variable declaration has the same form as its use, which simplifies the parser and enables reusing code in the compiler.
It makes more sense if you read in a more "old-school" way:
int *p;
"*p is an int"
(Equivalent translation: "p is a pointer to int")
int *p, x;
"*p and x are both ints"
("p is a pointer to int, and x is an int")
int (*q)[3];
"*q is an array of three ints", or "(*q)[x] is an int"
("q is a pointer to an array of three ints")
int (*fp)(int,int);
"*fp is a function that takes two ints and returns an int"
("fp is a pointer to a function that takes two ints and returns an int")
int (*(*foo)())[3];
"*(*foo)() is an array of three ints" (alternatively, "(*(*foo)())[x] is an int) - or, in other words,
"(*foo)() is a pointer to an array of three ints" - or, in other words,
"foo is a pointer to a function that takes no arguments and returns a pointer to an array of three ints"
A slightly unreadable effect of this is that
int *p, x, (*q)[3], (*fp)(int,int), (*(*foo)())[3];
declares all of the above at once.
That's just the syntax for function pointers.
You would see the same thing if you just declare a variable.
int foo; // Normal
int (*bar)(int, int); // bar is of type int(*)(int,int)
Personally i prefer to use using = ... which in my opinion is more clear.
using fp_GetBiggerElement = int (*)(int,int);
This syntax comes from the C-way of reading variables.
Ever wondered why we need an asterisk, for every pointer we want to declare in a single expression?
int *p1, *p2, p3; // p3 is not a pointer
C++ people generally tend to see a variable having a specific type, which can be a pointer (in other words, they see the pointer characteristics as property of the type). That's why they usually prefer writing
int* p1; // notice asterisk grouped with type
C people rather read as: I have a variable p1, and if I dereference it, I get type int (so p1 being a pointer is deduced information, i. e. they see the pointer characteristics rather as property of the variable; and that's why they rather group the asterisk to the name: int *p1;).
Pretty similar for function pointers:
int (*fp) (int, int);
I have a variable fp, and if I dereference it, I get int (int, int). Same pattern then for the typedef. On the other hand, the (new) C++ way for defining an alias reflects much better the C++ way of thinking:
using fp = int (*)(int, int);
I have a variable, and it's type is a pointer (to whatever) right from the start – well, not fully consistently, though: With C++ way of thinking, function pointers might rather look like int(int, int)* or maybe requiring parentheses (int(int, int))*, but OK, that's not the way it is (wanting to stay compatible with C being reason for).
typedef declarations are similar to simple declarations but instead of declaring an identifier of a derclarator as an identifier of an object or a function they declare an identifier of a declarator as an alias for the specified type.
Consider the following examples of simple declarations
int x;
unsigned int a[10][20];
int unsigned ( *p )[10][20];
void ( *f )( int, int );
double h( double );
They declare several objects and the function h.
Now place in these declarations decl-specifier typedef (in any order relative to other decl-specifiers) and you will get that the declared identifiers become aliases of types.
typedef int x;
unsigned typedef int a[10][20];
int unsigned typedef ( *p )[10][20];
void typedef ( *f )( int, int );
typedef double h( double );
That is x is an alias of the type int. a is an alias for the type unsigned int [10][20]. p is an alias for the pointer type unsigned int ( * )[10][20]. f is an alias for the function pointer void ( * )( int, int ). And h in an alias for the function type double( double ).

Unusual variable declaration in C++ [duplicate]

For example a declaration such as that:
int (x) = 0;
Or even that:
int (((x))) = 0;
I stumbled upon this because in my code I happened to have a fragment similar to the following one:
struct B
{
};
struct C
{
C (B *) {}
void f () {};
};
int main()
{
B *y;
C (y);
}
Obviously I wanted to construct object C which then would do something useful in its destructor. However as it happens compiler treats C (y); as a declaration of variable y with type C and thus it prints an error about y redefinition. Interesting thing is that if I write it as C (y).f () or as something like C (static_cast<B*> (y)) it will compile as intended. The best modern workaround is to use {} in constructor call, of course.
So as I figured out after that, it's possible to declare variables like int (x) = 0; or even int (((x))) = 0; but I've never seen anyone actually using declarations like this. So I'm interested -what's the purpose of such possibility because for now I see that it only creates the case similar to the notorious "most vexing parse" and doesn't add anything useful?
Grouping.
As a particular example, consider that you can declare a variable of function type such as
int f(int);
Now, how would you declare a pointer to such a thing?
int *f(int);
Nope, doesn't work! This is interpreted as a function returning int*. You need to add in the parentheses to make it parse the right way:
int (*f)(int);
The same deal with arrays:
int *x[5]; // array of five int*
int (*x)[5]; // pointer to array of five int
There's generally allowed to use parentheses in such declarations because the declaration, from the syntactical point of view looks always like this:
<front type> <specification>;
For example, in the following declaration:
int* p[2];
The "front type" is int (not int*) and the "specification" is * p[2].
The rule is that you can use any number of parentheses as needed in the "specification" part because they are sometimes inevitable to disambiguate. For example:
int* p[2]; // array of 2 pointers to int; same as int (*p[2]);
int (*p)[2]; // pointer to an array of 2 ints
The pointer to an array is a rare case, however the same situation you have with a pointer to function:
int (*func(int)); // declares a function returning int*
int (*func)(int); // declares a pointer to function returning int
This is the direct answer to your question. If your question is about the statement like C(y), then:
Put parentheses around the whole expression - (C(y)) and you'll get what you wanted
This statement does nothing but creating a temporary object, which ceases to living after this instruction ends (I hope this is what you intended to do).

Why is the constructor not called when assigning a functor to a std::function? [duplicate]

For example a declaration such as that:
int (x) = 0;
Or even that:
int (((x))) = 0;
I stumbled upon this because in my code I happened to have a fragment similar to the following one:
struct B
{
};
struct C
{
C (B *) {}
void f () {};
};
int main()
{
B *y;
C (y);
}
Obviously I wanted to construct object C which then would do something useful in its destructor. However as it happens compiler treats C (y); as a declaration of variable y with type C and thus it prints an error about y redefinition. Interesting thing is that if I write it as C (y).f () or as something like C (static_cast<B*> (y)) it will compile as intended. The best modern workaround is to use {} in constructor call, of course.
So as I figured out after that, it's possible to declare variables like int (x) = 0; or even int (((x))) = 0; but I've never seen anyone actually using declarations like this. So I'm interested -what's the purpose of such possibility because for now I see that it only creates the case similar to the notorious "most vexing parse" and doesn't add anything useful?
Grouping.
As a particular example, consider that you can declare a variable of function type such as
int f(int);
Now, how would you declare a pointer to such a thing?
int *f(int);
Nope, doesn't work! This is interpreted as a function returning int*. You need to add in the parentheses to make it parse the right way:
int (*f)(int);
The same deal with arrays:
int *x[5]; // array of five int*
int (*x)[5]; // pointer to array of five int
There's generally allowed to use parentheses in such declarations because the declaration, from the syntactical point of view looks always like this:
<front type> <specification>;
For example, in the following declaration:
int* p[2];
The "front type" is int (not int*) and the "specification" is * p[2].
The rule is that you can use any number of parentheses as needed in the "specification" part because they are sometimes inevitable to disambiguate. For example:
int* p[2]; // array of 2 pointers to int; same as int (*p[2]);
int (*p)[2]; // pointer to an array of 2 ints
The pointer to an array is a rare case, however the same situation you have with a pointer to function:
int (*func(int)); // declares a function returning int*
int (*func)(int); // declares a pointer to function returning int
This is the direct answer to your question. If your question is about the statement like C(y), then:
Put parentheses around the whole expression - (C(y)) and you'll get what you wanted
This statement does nothing but creating a temporary object, which ceases to living after this instruction ends (I hope this is what you intended to do).

Why does C++ allow us to surround the variable name in parentheses when declaring a variable?

For example a declaration such as that:
int (x) = 0;
Or even that:
int (((x))) = 0;
I stumbled upon this because in my code I happened to have a fragment similar to the following one:
struct B
{
};
struct C
{
C (B *) {}
void f () {};
};
int main()
{
B *y;
C (y);
}
Obviously I wanted to construct object C which then would do something useful in its destructor. However as it happens compiler treats C (y); as a declaration of variable y with type C and thus it prints an error about y redefinition. Interesting thing is that if I write it as C (y).f () or as something like C (static_cast<B*> (y)) it will compile as intended. The best modern workaround is to use {} in constructor call, of course.
So as I figured out after that, it's possible to declare variables like int (x) = 0; or even int (((x))) = 0; but I've never seen anyone actually using declarations like this. So I'm interested -what's the purpose of such possibility because for now I see that it only creates the case similar to the notorious "most vexing parse" and doesn't add anything useful?
Grouping.
As a particular example, consider that you can declare a variable of function type such as
int f(int);
Now, how would you declare a pointer to such a thing?
int *f(int);
Nope, doesn't work! This is interpreted as a function returning int*. You need to add in the parentheses to make it parse the right way:
int (*f)(int);
The same deal with arrays:
int *x[5]; // array of five int*
int (*x)[5]; // pointer to array of five int
There's generally allowed to use parentheses in such declarations because the declaration, from the syntactical point of view looks always like this:
<front type> <specification>;
For example, in the following declaration:
int* p[2];
The "front type" is int (not int*) and the "specification" is * p[2].
The rule is that you can use any number of parentheses as needed in the "specification" part because they are sometimes inevitable to disambiguate. For example:
int* p[2]; // array of 2 pointers to int; same as int (*p[2]);
int (*p)[2]; // pointer to an array of 2 ints
The pointer to an array is a rare case, however the same situation you have with a pointer to function:
int (*func(int)); // declares a function returning int*
int (*func)(int); // declares a pointer to function returning int
This is the direct answer to your question. If your question is about the statement like C(y), then:
Put parentheses around the whole expression - (C(y)) and you'll get what you wanted
This statement does nothing but creating a temporary object, which ceases to living after this instruction ends (I hope this is what you intended to do).

What does this typedef definition mean?

I have seen the following (C++):
typedef n *(m)(const n*, const n*);
What does it mean and how can it be used?
I understand this:
typedef n (*myFunctP)(const n*, const n*);
but what is the difference to the typedef above?
(Hope this is no duplicate, did not find something similar...)
I asked geordi to win me some rep:
<tomalak> << TYPE_DESC<m>; struct n {}; typedef n *(m)(const n*, const n*);
<geordi> function taking 2 pointers to constant ns and returning a pointer to a n
C type declaration syntax is horrible and it does become particularly apparent when you start doing complex declarations like this. Notice how the return type and arguments are written around the m, not the n, which is totally backwards to intuition since it's m that you're creating.
Your second example is:
<tomalak> << TYPE_DESC<m>; struct n {}; typedef n (*m)(const n*, const n*);
<geordi> pointer to a function taking 2 pointers to constant ns and returning a n
By moving the *, you are no longer applying it to the function type's return type, but to the function type itself.
In C++11, unless you have a desperate need for your calls to be hyper-efficient, please stick to the following, for the love of Cthulhu! :-)
typedef std::function<n*(const n*, const n*)> m;
If you wish to stick to function pointers then you can:
using m = n*(const n*, const n*);
Prior to that you can use boost::function or learn the horrific C declarator rules. It is true that you should know them; it's just that hopefully you won't have to use them too often.
The first typedef creates an alias for a function which takes 2 parameters and returns a pointer-to-n.
The second typedef creates an alias for a pointer-to-function which takes 2 parameters and returns an n by value.
In the first case the typedef defines an alias for a function type that has two parameters of type const n *and return type n *
In the second case instead of the function type there is a declaration of a function pointer having return type n.
In the first case you could write also for example
typedef n * ( (m)(const n*, const n*) );
It is equivalent to your typedef.
As for the usage you can use it as a function declaration. For exmaple
m MyFunc;
Another example
struct A
{
typedef int n;
typedef n ( Operation )( n, n ) const;
Operation Add;
Operation Subtract;
Operation Division;
Operation Multiply;
};
// and below the function definitions

Categories