function pointer without typedef - c++

Is it posible to use the type of a prefiously declared function as a function pointer without using a typedef?
function declaration:
int myfunc(float);
use the function declaration by some syntax as function pointer
myfunc* ptrWithSameTypeAsMyFunc = 0;

Not as per the 2003 standard. Yes, with the upcoming C++0x standard and MSVC 2010 and g++ 4.5:
decltype(myfunc)* ptrWithSameTypeAsMyFunc = 0;

Yes, it is possible to declare a function pointer without a typedef, but no it is not possible to use the name of a function to do that.
The typedef is usually used because the syntax for declaring a function pointer is a bit baroque. However, the typedef is not required. You can write:
int (*ptr)(float);
to declare ptr as a function pointer to a function taking float and returning int -- no typedef is involved. But again, there is no syntax that will allow you to use the name myfunc to do this.

Is it posible to use the type of a prefiously declared function as a function pointer without using a typedef?
I'm going to cheat a bit
template<typename T>
void f(T *f) {
T* ptrWithSameTypeAsMyFunc = 0;
}
f(&myfunc);
Of course, this is not completely without pitfalls: It uses the function, so it must be defined, whereas such things as decltype do not use the function and do not require the function to be defined.

No, not at the present time. C++0x will change the meaning of auto, and add a new keyword decltype that lets you do things like this. If you're using gcc/g++, you might also look into using its typeof operator, which is quite similar (has a subtle difference when dealing with references).

No, not without C++0x decltype:
int myfunc(float)
{
return 0;
}
int main ()
{
decltype (myfunc) * ptr = myfunc;
}

gcc has typeof as an extension for C (don't know about C++) ( http://gcc.gnu.org/onlinedocs/gcc/Typeof.html ).
int myfunc(float);
int main(void) {
typeof(myfunc) *ptrWithSameTypeAsMyFunc;
ptrWithSameTypeAsMyFunc = NULL;
return 0;
}

int (*ptrWithSameTypeAsMyFunc)(float) = 0;
See here for more info on the basics.

Related

Pointer to function with default arguments

Lets assume that we have a function
int foo (std::string, size_t = 0) { return 42; }
and I would like to call this function using wrapper function
template <typename T>
auto boo (std::string s) {
return (*T::value) (s);
}
So, T should contain a pointer to appropriate function, so I declare it like this
struct Foo : std::integral_constant<int (*) (std::string, size_t), &foo> {};
and now the usage looks like this
std::cout << boo<Foo> ("b") << "\n"; // 42
On GCC 5.3.1 this code compiles fine but on GCC 6.3.1 and GCC 7.2.1 this fails to compile with an error
error: too few arguments to function
As far as I am concerned if I use a pointer to a function without wrapper template function
using Ptr = int (*) (std::string, size_t);
Ptr p = &foo;
auto x = p ("10");
then the error is present in all mentioned versions of GCC.
According to the latter example, does it mean that I can not use a pointer without explicitly specifying second argument even though pointed function does not need it?
According to the main example does it mean that GCC 5.3.1 incorrectly implements this behavior in connection with template wrapper?
It's fine to use a function with default arguments using any of its possible signatures, but you've introduced an inconsistency yourself. You've specifically defined Foo as wrapping a pointer to a two-argument function, so you'd better call it with two arguments. If you want to call it with one argument, use it as a pointer to a one-argument function.
I'm not sure what you're trying to accomplish with integral_constant.

QSet<func pointer> does not compile by gcc

I'm trying to use QSet for storing a list of function pointers. See this code for more details. The problem is that this code does not compile by gcc/mingw. MSVC compiles it normally. What am I doing wrong?
typedef intptr_t (*UikHook)(intptr_t);
...
typedef struct
{
QSet<UikHook>* qsetSubscribers;
//QMutex* qmutexHook;
} THookableEvent;
...
THookableEvent* p = qmapHooks_.value(name);
if (p->qsetSubscribers == 0)
p->qsetSubscribers = new QSet<UikHook>();
p->qsetSubscribers->insert(hookProc);
error: no matching function for call to ‘qHash(long int (* const&)(long int))’
Perhaps, I should to declare operator== and function qHash() for type UikHook as it said in the docs, but I dont know how to do it because when I'm declaring opertator==, I get the following error:
inline bool operator==(const UikHook &e1, const UikHook &e2)
error: ‘bool operator==(intptr_t (* const&)(intptr_t), intptr_t (* const&)(intptr_t))’
must have an argument of class or enumerated type
P.S. I'm using Qt 5.8, gcc 6.2, msvc2015
Update: Solved by replacing QSet to QVector.
You can't define an operator== for built-in types, such as pointers, integers or floating-point numbers. They already have it. You just need to provide a qHash.
Using function pointers is not really the best practice in C++. In early C++ versions, functors were used instead. Since C++11, there are real function objects. You can convert a function pointer to an object via std::function() (Reference).
If the compilers you listed are the ones you need to support, I strongly suggest using std::function instead of function pointers.
Try (warning, brain compile):
template <typename R, typename ...A>
inline uint qHash(R (*)(A...) const f) noexcept
{
return std::hash<R (*)(A...)>()(f);
}
Qt is in a fix here, since it can't use the STL and hashing function pointers is somewhat compiler specific.

using typedef to wrap functions

One of my teachers use this type declaration:
typedef void (*SortFunction)(int a[], int n);
to create a type that can hold a pointer to a function
and that can be used to call that function later on in a program.
I also know that to pass a function as a parameter you have to
wrap the function name in parenthesis and wrap the function's
parameters in parenthesis after the function name as well like so
function someFunction( (anotherfunction)(type arg1, type arg2,...)){
...
}
What I want to know is why must you wrap a function in parenthesis like this? is this a built in function of most c++ compilers or is it simply a trick that we programmers use
in order to enable functions as arguments within our code? also, why does "SortFunction"
in the typedef statement need to be referenced, why can't the variable you use to utilize SortFunction just hold the function instead of pointing to it?
There's nothing special about function arguments. Whenever you declare a function pointer (as a local variable, global variable, class member variable, function parameter, typedef, etc.), it's always declared like so:
return_type (*var_name)(T1 param1, T2 param2, /* etc. */ );
// ^
// |
// This * is very important!
Where var_name is the name of the function pointer variable. The reason the parentheses are needed around *var_name is due to operator precedence: without the parentheses, the * (indicating that something's a pointer) would match with the function's return type, and instead you'd get something like a return type of int* (pointer to int) instead of plain int.
You can't pass a function as an argument because functions are not first-class objects in C and C++. The only way to pass a function is my passing a pointer to the function.
"I also know that to pass a function as a parameter you have to wrap the function name in parenthesis..." You "know " incorrectly.
In order to pass function pointer as a parameter you don't have to wrap the name in parentheses. For example, this will work perfectly fine
void foo(int i) {
}
void bar(void f(int)) {
f(5);
}
int main() {
bar();
}
In the above example function bar receives a pointer to function foo as a parameter and calls foo through that pointer, passing 5 as an argument. As you can see, function name f in the parameter declaration is not wrapped into parentheses.
In this case, once again, the type of parameter f is actually a pointer to a function, even though it is not explicitly declared as a pointer. When function type is used in function parameter declarations, it is automatically implicitly "replaced" with function pointer type by the compiler.
If you wanted to use the function pointer type explicitly, you have to declare bar as
void bar(void (*f)(int)) {
f(5);
}
In this case the parentheses in (*f) are necessary to assure that the * will get bound to f and not to void. Without parentheses the void *f(int) declaration would stand for "function returning void *" instead of the desired "pointer to function returning void".
It is a matter of syntax. Your first typedef defines a type which is a function receiving a vector of int and a int and returning nothing (void).
A variable of type SortFunction will be conceptually as any other variable, although it points to some function. The advantage is that you can change the function it points to and/or call the function dynamically.
What I want to know is why must you wrap a function in parenthesis like this?
Because there had to be some way to identify a function pointer to the compiler (or rather, the parser) and that way seemed as good as any. In C++11 land, you might use this instead: std::function<void(std::array<int>&)> instead.
is this a built in function of most c++ compilers or is it simply a trick that we programmers use in order to enable functions as arguments within our code?
Function pointers need a little bit of additional magic, and without compiler support they would be very, very inconvenient to use. I'm also reasonably certain that it is in the nature of programming that almost all programmer tricks are ultimately functions of the compiler!
also, why does "SortFunction" in the typedef statement need to be referenced, why can't the variable you use to utilize SortFunction just hold the function instead of pointing to it?
Hmm. Not totally sure what you mean here. Do you mean "why does this need to be a typedef at all... why couldn't I just write out the whole function pointer prototype in my function arguments"? Cos you can:
void foo(void(*funcptr)()) {}
If you meant "why do function pointers have to point at a function instead of having the code inline" then for that you need C++11 and lambdas:
#include <iostream>
#include <functional>
void foo(std::function<void(void)> bar) { bar(); }
int main(int argc, char* argv[])
{
foo([]() { std::cout << "hi!" << std::endl; });
}
(again, special syntax needed for lambdas, [](){}, just to tell the parser what is going on)

function pointers and return type conversions

Suppose I have a function that performs some side effect and then returns an answer:
int foo()
{
perform_some_side_effect();
return 42;
}
I want to bind foo to a function pointer, but I'm not interested in the answer, just the side effect:
void (*bar)() = foo;
However, this appears to be a type error:
error: invalid conversion from ‘int (*)()’ to ‘void (*)()’
What is the rationale behind that error? Why doesn't the type system allow me to ignore the answer?
On a side note, it works if I wrap the function pointer in a std::function:
std::function<void()> baz = foo;
How does std::function (apparently) manage to circumvent this restriction in the type system?
What is the rationale behind that error? Why doesn't the type system allow me to ignore the answer?
The reason is that the types are different, and the generated code at the place of call (through the function pointer) is different. Consider a calling convention where all arguments are written to the stack and space for the return value is also reserved in the stack. If the call goes through a void (*)() then no space will be reserved in the stack for the return value, but the function (unaware of how it is being called) will still write the 42 to the location where the caller should have reserved space.
How does std::function (apparently) manage to circumvent this restriction in the type system?
It does not. It creates a function object that wraps the call to the actual function. It will contain a member like:
void operator()() const {
foo();
}
Now when the compiler processes the call to foo it knows what it has to do to call a function that returns an int and it will do so according to the calling convention. Because the template does not return, it will just ignore the value --that was actually returned.
std::function need only be source compatible- that is, it can generate a new class which generates new caling code that ignores the result. The function pointer must be binary compatible and cannot do that job- void(*)() and int(*)() point to the exact same code.
You can think of std::function<> doing this for your particular case:
void __func_void()
{
foo();
}
It's actually a bit more complicated than that, but the point is that it generates template code together with type-erasure to not care about the specifics.
In addition to what others have been saying, the caller also need the return type to know what destructor it should invoke on the result (the return value may be a temporary).
Unfortunately it is not as easy as
auto (*bar)() = foo;
Although GCC and Clang accept this. I need to recheck the spec to see whether that's actually correct.
Update: The spec says
The auto type-specifier signifies that the type of a variable being declared shall be deduced from its initializer or that a function declarator shall include a trailing-return-type.
This can be misleading when read fast, but this is implemented by GCC and clang to only apply to the toplevel declarator. In our case, this is a pointer declarator. The declarator nested in it is a function declarator. So just substitute auto for void and then the compiler will deduce the type for you.
By the way, you can always make this work manually, but it takes some trickery to make it work
template<typename FunctionType>
struct Params;
template<typename ...Params>
struct Params<void(Params...)> {
template<typename T>
using Identity = T;
template<typename R>
static Identity<R(Params...)> *get(R f(Params...)) {
return f;
}
};
// now it's easy
auto bar = Params<void()>::get(foo);

C++ typedef member function signature syntax

I want to declare type definition for a member function signature. Global function typedefs look like this:
typedef int (function_signature)(int, int);
typedef int (*function_pointer) (int, int);
But I'm not able to the same thing for a member function:
typedef int (foo::memberf_signature)(int, int); // memberf_pointer is not a member of foo
typedef int (foo::*memberf_pointer)(int, int);
It sounds logically to me, because foo:: is the syntax to access a member in the class foo.
How can I typedef just the signature?
For questions regarding the awkward function pointer syntax, I personally use a cheat-sheet: The Function Pointers Tutorial (downloadable here, thanks to Vector for pointing it out).
The signature of a member function, however, is a bit different from the signature of a regular function, as you experienced.
As you probably know, a member function has a hidden parameter, this, whose type need be specified.
// C++11 and above.
using Member = int (Foo::*)(int, int);
// C++03 and below.
typedef int (Foo::*Member)(int, int);
does let you specify that the first element passed to the function will be a Foo* (and thus your method really takes 3 arguments, when you think of it, not just 2.
However there is another reason too, for forcing you to specify the type.
A function pointer might refer to a virtual function, in which case things can get quite complicated. Therefore, the very size of the in-memory representation changes depending on the type of function. Indeed, on Visual Studio, a function pointer's size might vary between 1 and 4 times the size of a regular pointer. This depends on whether the function is virtual, notably.
Therefore, the class the function refers to is part of the signature, and there is no work-around.
You can factor out the target class in modern C++ (post 11) by utilizing the 'typedefing' qualities of template aliases. What you need would look like like:
template<typename T>
using memberf_pointer = int (T::*)(int, int);
Yet at the point of declaration, a pointer to member function utilizing this syntax would need to specify the target class:
// D is a member function taking (int, int) and returning int
memberf_pointer<foo> mp = &foo::D;
The reason it doesn't work with your current syntax is that operator precedence dictates that you're referring to a function named foo::memberf_signature, not any sort of type.
I don't know for sure if you can do this or not, but I couldn't come up with any combination of parenthese that induced the code to compile with g++ 4.2.
It works for me:
#include <iostream>
class foo
{
public:
int g (int x, int y) { return x + y ; }
} ;
typedef int (foo::*memberf_pointer)(int, int);
int main()
{
foo f ;
memberf_pointer mp = &foo::g ;
std::cout << (f.*mp) (5, 8) << std::endl ;
}
Well basically it can't work (at least I know no way using g++);
Using borland c++ compiler there would be the __closure keyword.
The reason why it does not compile is, that sizeof the functionpointer (on a x86 machine) occupies always <<32bits>>; but if you want to point to a class (interface) signature, the sizeof has to be 64bit: 32 bit for the this pointer (as the class interface is in the memory only once) and 32 bit for the actual function
But the __closure keyword is a bcb language 'hack' not standardized...