Is it possible to initialize function pointer with function declaration in C++? I mean, something like this:
void (*pointer)(void) = &( void function(void) );
or this:
void (*pointer)(void) = void function(void);
It's almost possible, you just have to reverse the order: declare the function first, and then initialise the pointer with its address:
void function(), (*pointer)() = &function;
[Live example]
However, I consider this ugly, unreadable code, and would never suggest actually using it. So, my answer is: "It's possible, but should never be done." (I can imagine it being excusable in certain situations involving macros, but that's about it).
No, as any variable in C++ (including function pointers) has to be initialized with an expression, and a function declaration is not an expression.
You might want to use a captureless lambda expression instead:
void (*pointer)() = []{ std::cout << "hello world\n"; };
No, since a pointer - including a function pointer - must be initialised using an expression. A function declaration is not an expression.
However, an expression can be composed using previously declared functions (or variables) in the compilation unit (aka source file)
void function(); // declare the function, defined elsewhere
void (*pointer)() = function; // function name in an expression is converted to a function pointer
It is possible (not recommended for readability purposes) to combine the two in one declaration of multiple variables.
void function(), (*pointer)() = function;
An initializer may not be a declaration. It does not make sense. You already specified the type of the pointer when you declared it.
If you declare a pointer and want to initialize it when you have to assign it some value.
Here is a demonstrative program. It uses an array of function pointers (to be more interesting).
#include <iostream>
void f1()
{
std::cout << "Hello ";
}
void f2()
{
std::cout << "Roman Kwaśniewski";
}
void f3()
{
std::cout << '\n';
}
int main()
{
void ( *fp[] )() = { f1, f2, f3 };
for ( auto &func : fp ) func();
}
The program output is
Hello Roman Kwaśniewski
Pay attention to that you need not to specify for example &f2 as initializer because a function designator is implicitly converted to pointer.
Though for example this initialization is also correct
void ( *fp[] )() = { f1, %f2, f3 };
and is equivalent to the previous one.
Related
In the following program, How do I typecast bar to foo?
#include <iostream>
namespace NA {
class A {
public:
int (*foo)(int);
};
}
namespace NB {
class B : public NA::A {
public:
int bar(int i) {
std::cout << i << std::endl;
return i*2;
}
B() {
this->foo = bar; // how to type cast this fn pointer?
}
};
}
int main() {
NA::A *a = new NB::B();
std::cout << a->foo(2) << std::endl;
}
I tried typecasting as follows but something is going terribly wrong when I run the program:
B() {
typedef int (*TypeFoo)(int);
this->foo = reinterpret_cast<TypeFoo> (&bar);
}
Here's the result when I run:
$ ./a.out
31947824
63895648
I was expecting 2 and 4. How does one typecast the member function pointers above?
Update:
After seeing responses indicating there's no solution to the above problem, I am updating this question further with the specific problem I was trying to address.
Please see https://boringssl.googlesource.com/boringssl/+/HEAD/include/openssl/ssl.h#1173 -- I am trying to have different instances of the struct ssl_private_key_method_st operate on different private keys. I was trying to have another struct inherit from ssl_private_key_method_st and have the sign/decrypt/complete methods operate on instance variables of the inherited struct.
I am aware of using SSL_[sg]et_ex_data to pass data to these functions indirectly, but I was looking for a more simpler / direct way of passing instance data to these functions if possible.
You are running into undefined behavior.
TypeFoo and bar are different types of function pointers (int (*)(int) and int (NB::B::*)(int) respectively).
While it is possible to cast one to the other, using the result to call the function will result in undefined behavior.
8.2.10 Reinterpret cast [expr.reinterpret.cast]
...
6. A function pointer can be explicitly converted to a function pointer of a different type. [ Note: The effect of calling a function through a pointer to a function type (11.3.5) that is not the same as the type used in the definition of the function is undefined. —end note ] Except that converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are function types) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified. [ Note: See also 7.11 for more
details of pointer conversions. —end note ]
Short answer: you don't.
Non-static member function pointers are weird. Calling one involves a secret this parameter, and they may or may not be virtual. This makes them impossible to mix with ordinary function pointers.
You should consider using std::function<int(int)> instead of int (*)(int). This would allow you to store something like the following lambda:
B(){
std::function<int(int)> myfn = [this](int x){
return bar(x);
};
}
This lambda captures the current object by reference, and this reference is stored inside the std::function object itself. But you can just as well assign any other function to a std::function, directly or through a lambda or bind expression.
On the other hand, if your bar method doesn't really doesn't depend on an instance, just make it static. This will allow it to mix with regular function pointers, since it no longer needs a secret this and cannot be virtual.
static int bar(int i) {
std::cout << i << std::endl;
return i*2;
}
Written like this, &B::bar can be assigned to a regular int (*)(int) function pointer.
Your TypeFoo defines a pointer to a regular function while bar is a method. Each non-static method has an implicit first parameter this.
So you should decide what do you need: a regular function (in this case make the bar static) or a method, in this case you should typedef like that:
typedef int (B::*TypeFoo)(int);
The reinterpret_cast is an error prone practice. If you cannot cast without it - there is high probability that your code is not correct.
Invoking a member function pointer is a real pain. I suggest you go about this the following way, simplifying much of the context handling:
#include <iostream>
namespace NA {
class A {
public:
int (A::*foo)(int);
};
}
namespace NB {
class B : public NA::A {
public:
int bar(int i) {
std::cout << i << std::endl;
return i*2;
}
int callFoo(int x) {
return (this->*foo)(x);
}
B() {
this->foo = (int(A::*)(int)) (&B::bar);
}
};
}
int main() {
NA::A *a = new NB::B();
std::cout << ((NB::B*)a)->callFoo(2) << std::endl;
}
The following is a perfectly legal C++ code
void foo (int) {
cout << "Yo!" << endl;
}
int main (int argc, char const *argv[]) {
foo(5);
return 0;
}
I wonder, if there a value to ever leave unnamed parameters in functions, given the fact that they can't be referenced from within the function.
Why is this legal to begin with?
Yes, this is legal. This is useful for implementations of virtuals from the base class in implementations that do not intend on using the corresponding parameter: you must declare the parameter to match the signature of the virtual function in the base class, but you are not planning to use it, so you do not specify the name.
The other common case is when you provide a callback to some library, and you must conform to a signature that the library has established (thanks, Aasmund Eldhuset for bringing this up).
There is also a special case for defining your own post-increment and post-decrement operators: they must have a signature with an int parameter, but that parameter is always unused. This convention is bordering on a hack in the language design, though.
Of course not naming a parameter is legal when just declaring the function, but it's also legal in the implementation. This last apparently strange version is useful when the function needs to declare the parameter to have a specific fixed signature, but the parameter is not needed.
This may happen for example for a method in a derived class, for a callback function or for a template parameter.
Not giving the parameter a name makes clear that the parameter is not needed and its value will not be used. Some compilers if you instead name a parameter and then simply don't use it will emit a warning that possibly there is a problem with the function body.
Just wanted to mention a specific (unusual but interesting) usecase - the "passkey idiom".
It uses a "dummy" parameter of a type, constructor of which is accessible only to its friends. Its purpose is only to check, whether the caller has access to this constructor. So it needs no name as it is not used in the function, only the compiler uses it.
It's used like this:
class Friendly; // Just a forward declaration
class Key {
private:
Key() {}
friend class Friendly;
};
class Safe() {
public:
static int locked(Key, int i) {
// Do something with `i`,
// but the key is never used.
return i;
}
private:
static void inaccessible() {}
};
class Friendly {
public:
void foo() {
int i = Safe::locked(Key(), 1); // OK
int j = Safe::locked({}, 2); // OK, sice C++11
}
void bar() {
Safe::inaccessible(); // Not OK, its inaccessible
}
};
int i = Safe::locked(3); // Not OK, wrong parameters
int j = Safe::locked(Key(), 4); // Not OK, `Key` constructor is inaccessible
int k = Safe::locked({}, 5); // Not OK, `{}` means `Key()` implicitly
I just want to add that there is sometimes a difference whether you name a parameter or not. For example, the compiler treats a named rvalue reference as an lvalue and an unnamed rvalue reference as an rvalue.
// named-reference.cpp
// Compile with: /EHsc
#include <iostream>
using namespace std;
// A class that contains a memory resource.
class MemoryBlock
{
// TODO: Add resources for the class here.
};
void g(const MemoryBlock&)
{
cout << "In g(const MemoryBlock&)." << endl;
}
void g(MemoryBlock&&)
{
cout << "In g(MemoryBlock&&)." << endl;
}
MemoryBlock&& f(MemoryBlock&& block)
{
g(block);
return block;
}
int main()
{
g(f(MemoryBlock()));
}
This example produces the following output:
In g(const MemoryBlock&).
In g(MemoryBlock&&).
In this example, the main function passes an rvalue to f. The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g).
The following is a perfectly legal C++ code
void foo (int) {
cout << "Yo!" << endl;
}
int main (int argc, char const *argv[]) {
foo(5);
return 0;
}
I wonder, if there a value to ever leave unnamed parameters in functions, given the fact that they can't be referenced from within the function.
Why is this legal to begin with?
Yes, this is legal. This is useful for implementations of virtuals from the base class in implementations that do not intend on using the corresponding parameter: you must declare the parameter to match the signature of the virtual function in the base class, but you are not planning to use it, so you do not specify the name.
The other common case is when you provide a callback to some library, and you must conform to a signature that the library has established (thanks, Aasmund Eldhuset for bringing this up).
There is also a special case for defining your own post-increment and post-decrement operators: they must have a signature with an int parameter, but that parameter is always unused. This convention is bordering on a hack in the language design, though.
Of course not naming a parameter is legal when just declaring the function, but it's also legal in the implementation. This last apparently strange version is useful when the function needs to declare the parameter to have a specific fixed signature, but the parameter is not needed.
This may happen for example for a method in a derived class, for a callback function or for a template parameter.
Not giving the parameter a name makes clear that the parameter is not needed and its value will not be used. Some compilers if you instead name a parameter and then simply don't use it will emit a warning that possibly there is a problem with the function body.
Just wanted to mention a specific (unusual but interesting) usecase - the "passkey idiom".
It uses a "dummy" parameter of a type, constructor of which is accessible only to its friends. Its purpose is only to check, whether the caller has access to this constructor. So it needs no name as it is not used in the function, only the compiler uses it.
It's used like this:
class Friendly; // Just a forward declaration
class Key {
private:
Key() {}
friend class Friendly;
};
class Safe() {
public:
static int locked(Key, int i) {
// Do something with `i`,
// but the key is never used.
return i;
}
private:
static void inaccessible() {}
};
class Friendly {
public:
void foo() {
int i = Safe::locked(Key(), 1); // OK
int j = Safe::locked({}, 2); // OK, sice C++11
}
void bar() {
Safe::inaccessible(); // Not OK, its inaccessible
}
};
int i = Safe::locked(3); // Not OK, wrong parameters
int j = Safe::locked(Key(), 4); // Not OK, `Key` constructor is inaccessible
int k = Safe::locked({}, 5); // Not OK, `{}` means `Key()` implicitly
I just want to add that there is sometimes a difference whether you name a parameter or not. For example, the compiler treats a named rvalue reference as an lvalue and an unnamed rvalue reference as an rvalue.
// named-reference.cpp
// Compile with: /EHsc
#include <iostream>
using namespace std;
// A class that contains a memory resource.
class MemoryBlock
{
// TODO: Add resources for the class here.
};
void g(const MemoryBlock&)
{
cout << "In g(const MemoryBlock&)." << endl;
}
void g(MemoryBlock&&)
{
cout << "In g(MemoryBlock&&)." << endl;
}
MemoryBlock&& f(MemoryBlock&& block)
{
g(block);
return block;
}
int main()
{
g(f(MemoryBlock()));
}
This example produces the following output:
In g(const MemoryBlock&).
In g(MemoryBlock&&).
In this example, the main function passes an rvalue to f. The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g).
My question is about using std::function to class methods. Suppose I have the following class hierarchy:
class Foo {
public:
virtual void print() {
cout << "In Foo::print()" << endl;
}
virtual void print(int) {
cout << "In Foo::print(int)" << endl;
}
};
class Bar : public Foo {
public:
virtual void print() override {
cout << "In Bar::print()" << endl;
}
virtual void print(int) override {
cout << "In Bar::print(int)" << endl;
}
}
Now there is another function which is supposed to dynamically call one of the two class methods depends on its input:
void call(Foo* foo, void (Foo::*func)(void)) {
(foo->*func)();
}
Foo* foo = new Foo();
Bar* bar = new Bar();
call(foo, &Foo::print);
call(bar, &Foo::print);
When I compile the above code snippet using g++/clang++, it works as expected, where the output is:
In Foo::print()
In Bar::print()
My questions are then:
since there are two functions (overloaded) with the same name: print, when I pass the address of class function: &Foo::print, how did the compiler know that I am actually calling Foo::print(void) but not Foo::print(int)?
is there another way that I can generalize the code above such that the second parameter of void call(Foo*, xxx) can be passed using both Foo::print(void) and Foo::print(int)
is there anyway to achieve this feature using new feature in C++11 std::function ? I understand that in order to use std::function with a non-static class method, I have to use std::bind to bind each class method with a specific class object, but that would be too inefficient for me because I have many class objects to be bound.
Since there are two functions (overloaded) with the same name: print, when I pass the address of class function: &Foo::print, how did the compiler knows that I am actually calling Foo::print(void) but not Foo::print(int)?
This is allowed because of [over.over]/p1:
A use of an overloaded function name without arguments is resolved in certain contexts to a function, a
pointer to function or a pointer to member function for a specific function from the overload set.
The compiler can use the target type of the parameter-type-list to determine which function from the overload set the pointer-to-member refers:
A use of an overloaded function name without arguments is resolved in certain contexts to a function, a
pointer to function or a pointer to member function for a specific function from the overload set. A function
template name is considered to name a set of overloaded functions in such contexts. The function selected
is the one whose type is identical to the function type of the target type required in the context. [ Note: .. ] The target can be
— an object or reference being initialized (8.5, 8.5.3, 8.5.4),
— the left side of an assignment (5.18),
— a parameter of a function (5.2.2),
— [..]
The name Foo:print represents an overload set which the compiler looks through to find a match. The target type Foo::print(void) is present in the overload set, so the compiler resolves the name to that overload.
Is there another way that I can generalize the code above such that the second parameter of void call(Foo*, xxx) can be passed using both Foo::print(void) and Foo::print(int)
There isn't a general way to do it with the name itself. The name has to be resolved to an overload. Instead, try changing the code to accept a function object like a lambda:
template<class Callable>
void call(Foo* foo, Callable&& callback) {
callback(foo);
}
int main()
{
call(foo, [] (Foo* f) { f->print(); f->print(1); });
}
First, std::bind is (almost) entirely outmoded by C++11 lambdas. Don't use std::bind if you can help it. One of these is much clearer than the others, using your example code:
const auto lambda = [=] { foo->print(); }; // Clear!
const auto binderv = std::bind( static_cast<void(Foo::*)()>( &Foo::print ), foo ); // Gets the void version
const auto binderi = std::bind( static_cast<void(Foo::*)(int)>( &Foo::print ), foo, std::placeholders::_1 ); // Gets the int version
//const auto binderv2 = std::bind( &Foo::print, foo ); // Error! Can't tell which Foo::print()
//const auto binderi2 = std::bind( &Foo::print, foo, std::placeholders::_1 ); // Error! Can't tell which Foo::print()
lambda(); // prints "void"
binderv(); // prints "void"
binderi(1); // prints "int"
Second, how does the compiler know which overloaded function to call? The same way it would if you were using non-member functions:
#include <iostream>
void call( void (*fn)() )
{
fn();
}
void print() { std::cout << "void\n"; }
void print(int) { std::cout << "int\n"; }
int main()
{
call( &print ); // prints "void"
}
Only one of those overloaded functions fits the called function's prototype, so the compiler knows. In the case of std::bind above, it can't quite tell, but you can force it with a cast, as I did.
Lambdas or std::function can wrap either of the member functions, but note that you can't overload a function on different std::function signatures. See here.
Update:
The right way to handle your question #3 -- to have one function call functions with drastically different signatures like yours -- is to use some intermediary like a functor (lambda, std::function, std::bind, hand-rolled functor) to erase the differences.
std::function<void()> objects that have the same signature, regardless of what the real functions you're calling have as their signature. std::function is more expensive (in terms of storing and calling) than a lambda but it has the advantage of having a typename that you can use if you need to store it in a container or something. Lambdas can sometimes be inlined away by the compiler if you play your cards right, so efficiency may still favor lambdas.
I need to use a function defined in one class in another class. Instead of rewriting the whole function, I tried to pass the function as a pointer, as below:
class C {
public:
int get(int x) { return x*x; }
};
struct S {
int (*func) (int x);
};
int main() {
C c;
S s;
cout << c.get(3) << endl;
s.func = &C::get;
cout << s.func(3) << endl;
return 0;
}
This doesn't work and gives the following error:
func_ptr.cpp: In function ‘int main()’:
func_ptr.cpp:42:18: error: cannot convert ‘int (C::*)(int)’ to ‘int (*)(int)’ in assignment
Is it possible to do something like this, and if so, how can I fix it? Moreover, if it is possible, can I use the pointer from an object instance instead of the class? That is, to possibly use variables defined in a specific class instance. Thanks.
C::get() is a non-static member function, which means it must be invoked on an instance of C. It has an implicit first argument, the this pointer, that must be passed to it when calling the function.
Since your C::get() doesn't seem to need access to any data members of C, you could make it a static member function.
static int get(int x) { return x*x; }
Now your code will work as is.
Another option is to change func so that it is a pointer to a member function of C
struct S {
int (C::*func) (int x);
};
And invoke it as
s.func = &C::get;
std::cout << (c.*(s.func))(3) << std::endl;
Yet another option would be to change the type of S::func to std::function<int(int)>. Now it can hold any callable (function pointer, functor, lambda) that takes a single int as an argument, and returns an int.
struct S {
std::function<int(int)> func;
};
s.func = std::bind(&C::get, &c, std::placeholders::_1);
std::cout << s.func(3) << std::endl;
A regular function and a member function are a bit different. To use a member function, you'll need an object to call it on (i.e. the this pointer in a member function body).
Take a look at std::function and std::bind, they are used to handle function like (callable) entities in a uniform way. They can manage global functions, static member functions, lambdas, regular member functions, functors, whatever that can be called like a function.
http://en.cppreference.com/w/cpp/utility/functional/function
http://en.cppreference.com/w/cpp/utility/functional/bind
http://en.cppreference.com/w/cpp/header/functional
e.g.:
struct S
{
std::function<int(int)> func;
};
C c;
S s;
s.func = std::bind( &C::get, &c, std::placeholders::_1 );
If you're OK with using STL then you can utilize std::function to hold a pointer to a function and std::bind to bind that particular pointer to a particular function. It makes your code look much more cleaner. std::bind looks for both static and non-static member functions. For non-static member function would need to pass the object reference so it will be able to point to the correct address.
Here is a code snippet to show how to use it:
std::bind(ClassName::MemberFunctionName, object, std::placeholders::_1)
std::placeholders::_1 means that ::MemberFunctionName accepts one parameter.