This question already has answers here:
Why does printing a function name returns a value?
(3 answers)
Closed 3 years ago.
Let's assume the following class Foo.
struct Foo
{
int i;
};
if I want to make an instance of this class and initialize it, I should do: Foo foo1 = Foo(); to call the constructor.
int main(void)
{
foo1 = Foo();
cout << foo1.i << " : " << foo1.j << endl; // " 0 "
}
then I thought I'd call the default constructor with the following line but it doesn't:
int main(void)
{
Foo foo2(); // most vexing parse
cout << foo2 << endl; // " 1 " ??? why?
foo2.i++; // error: request for member ‘i’ in ‘foo2’, which is of non-class type ‘Foo()’
}
Why is foo2 initialized to int(1) and not Foo()?
I know about the most vexing parse, it tells that, from my understanding, when a line can be interpreted as a function, it is interpreted as a function.
But foo1() is interpreted as an int, not a function, nor a Foo class.
The line Foo foo2() compiles because it is interpreted as a function prototype. OK.
Why does this line compiles? cout << foo2 << endl;
Does it print the address of the foo2 function?
As you said, Foo foo2(); is a function declaration. For cout << foo2, foo2 would decay to function pointer, and then converts to bool implicitly. As a non-null function pointer, the converted result is true.
Without using boolalpha, the std::basic_ostream<CharT,Traits>::operator<< would output 1 for true.
If boolalpha == 0, then converts v to type int and performs integer output.
You can see it more clearer with usage of std::boolalpha.
cout << boolalpha << foo2 << endl; // print out "true"
Related
This question already has answers here:
Is there a difference between foo(void) and foo() in C++ or C?
(4 answers)
Closed 3 years ago.
In this code I am overloading the function. But can someone tell me why there is void in the argument brackets of main function. I tried to remove void from the brackets of main function code still works. Any idea ?
#include <iostream.h>
class printData
{
public:
void print(int i)
{
cout << "Printing int: " << i << endl;
}
void print(double f)
{
cout << "Printing float: " << f << endl;
}
void print(char* c)
{
cout << "Printing character: " << c << endl;
}
};
int main(Void)
{
printData pd;
pd.print(5); // Call print to print integer
pd.print(500.263); // Call print to print float
pd.print("Hello C++"); // Call print to print character
return 0;
}
(void) is the list of parameters that main is expecting from its caller. In most cases, its caller is the operating system (or, strictly speaking, the startup code that calls the main function in your program). In C, a void parameter list explicitly states that the function does not expect to receive any parameters from its caller. In C++, a parameter list (void) has the same meaning as an empty parameter list (). Find More Here
This question already has answers here:
Why does printing a function name returns a value?
(3 answers)
Closed 3 years ago.
Let's assume the following class Foo.
struct Foo
{
int i;
};
if I want to make an instance of this class and initialize it, I should do: Foo foo1 = Foo(); to call the constructor.
int main(void)
{
foo1 = Foo();
cout << foo1.i << " : " << foo1.j << endl; // " 0 "
}
then I thought I'd call the default constructor with the following line but it doesn't:
int main(void)
{
Foo foo2(); // most vexing parse
cout << foo2 << endl; // " 1 " ??? why?
foo2.i++; // error: request for member ‘i’ in ‘foo2’, which is of non-class type ‘Foo()’
}
Why is foo2 initialized to int(1) and not Foo()?
I know about the most vexing parse, it tells that, from my understanding, when a line can be interpreted as a function, it is interpreted as a function.
But foo1() is interpreted as an int, not a function, nor a Foo class.
The line Foo foo2() compiles because it is interpreted as a function prototype. OK.
Why does this line compiles? cout << foo2 << endl;
Does it print the address of the foo2 function?
As you said, Foo foo2(); is a function declaration. For cout << foo2, foo2 would decay to function pointer, and then converts to bool implicitly. As a non-null function pointer, the converted result is true.
Without using boolalpha, the std::basic_ostream<CharT,Traits>::operator<< would output 1 for true.
If boolalpha == 0, then converts v to type int and performs integer output.
You can see it more clearer with usage of std::boolalpha.
cout << boolalpha << foo2 << endl; // print out "true"
So given a typedef that defines a function pointer with parameter names like this:
typedef void(*FOO)(const int arg);
Is there a way that I can just use this function pointer to define the signature of my function? Obviously this won't work, but I'd like to somehow use the typedef to specify a function signature with a corresponding type:
FOO foo {
cout << arg << endl;
}
Again, I know this doesn't work, and is bad syntax. It will just give the error:
error: arg was not declared in this scope
What you are trying to do will not work. FOO is an alias for void(*)(const int). so
FOO foo {
cout << arg << endl;
}
becomes
void(*)(const int) foo {
cout << arg << endl;
}
and that just doesn't work. What you can do though is define a macro that takes a name and use that to stamp out a function signature. That would look like
#define MAKE_FUNCTION(NAME) void NAME(const int arg)
MAKE_FUNCTION(foo){ std::cout << arg * 5 << "\n"; }
MAKE_FUNCTION(bar){ std::cout << arg * 10 << "\n"; }
int main()
{
foo(1);
bar(2);
}
The definition of a function pointer has nothing to do with the declaration nor the definition of a function so the answer is no.
You can do this actually. You can abuse lambdas to clone a function by assigning an auto lambda to the type. The downside is you lose access to the argument names, and have to access the arguments by index instead.
https://github.com/stevemk14ebr/PolyHook_2_0/blob/350f6723f0c12b93085273fc4a5208aaa36bf41a/polyhook2/IHook.hpp#L67-L150
here's an example of the usage
https://github.com/stevemk14ebr/PolyHook_2_0/blob/350f6723f0c12b93085273fc4a5208aaa36bf41a/UnitTests/windows/TestDetourx64.cpp#L22-L41
I want to save lambda expressions variables (like in the fist code block). The problem is that then I use a classes (like the second code block) the compiler return me some errors. I don"t know how to fix it.
I hope somebody can help me and explain, why it's not working like this. Thanks.
First Code:
// variable for function pointer
void (*func)(int);
// default output function
void my_default(int x) {
cout << "x =" << "\t" << x << endl << endl;
}
int main() {
cout << "Test Programm\n\n";
// 1. Test - default output function
cout << "my_default\n";
func = &my_default;
func(5);
// 2. Test - special output function 2
cout << "my_func2\n";
func = [](int x) { cout << "x =" << " " << x << endl << endl; };
func(5);
return 0;
}
Second Code:
class test {
private:
// variable for function pointer
void (*func)(int);
// default output function
void my_default(int x) {
cout << "x =" << "\t" << x << endl << endl;
}
public:
void dummy(void) {
// 1. Test - default output function
cout << "my_default\n";
func = &my_default;
func(5);
// 2. Test - special output function 2
cout << "my_func2\n";
func = [](int x)->int{ cout << "x =" << " " << x << endl << endl; };
func(5);
}
};
// entry
int main() {
cout << "Test Programm\n\n";
test a;
a.dummy();
return 0;
}
Compiler:
pi#raspberrypi ~/dev/property $ gcc -std=c++0x -o test2 test2.cpp -lstdc++
test2.cpp: In member function ‘void test::dummy()’:
test2.cpp:491:17: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say ‘&test::my_default’ [-fpermissive]
test2.cpp:491:17: error: cannot convert ‘void (test::*)(int)’ to ‘void (*)(int)’ in assignment
test2.cpp:496:77: error: invalid user-defined conversion from ‘test::dummy()::<lambda(int)>’ to ‘void (*)(int)’ [-fpermissive]
test2.cpp:496:28: note: candidate is: test::dummy()::<lambda(int)>::operator int (*)(int)() const <near match>
test2.cpp:496:28: note: no known conversion for implicit ‘this’ parameter from ‘int (*)(int)’ to ‘void (*)(int)’
The problem is that member functions are not normal functions, they can't be assigned to a function pointer because the type in which they are member is part of their type.
Also, a member function needs to have an object to be called on, which will be the this inside the function code.
You have several solutions:
allow only functions which are member of your class
void (*MyClass::func)(int); // but you can use it only with members of the class
use std::function
typedef std::function<void(int)> func;
The solution 2 is the simplest as std::function is designed to work with anything that is callable with the same signature as the one in the template parammetters.
Also, it's the only solution that allows you to store closures(objects from lambdas).
See C++11 styled callbacks? for details.
class test {
private:
// variable for function pointer
std::function< void ( int )> func;
// default output function
void my_default(int x) {
cout << "x =" << "\t" << x << endl << endl;
}
public:
void dummy(void) {
// 1. Test - default output function
cout << "my_default\n";
func = std::bind(&test::my_default, this, std::placeholders::_1);
// or
func = [&]( int i ){ my_default( i ); };
func(5);
// 2. Test - special output function 2
cout << "my_func2\n";
func = [](int x)->int{ cout << "x =" << " " << x << endl << endl; };
func(5);
}
};
// entry
int main() {
cout << "Test Programm\n\n";
test a;
a.dummy();
return 0;
}
A member function is not like an ordinary function, in that there has to be an instance of the class available in order to invoke it (i.e., the object that will become *this). You can't make an ordinary function pointer variable point to a member function.
If you want to create a function pointer that can be called using any instance of the class, you need a member function pointer. You would write
void (test::*func)(int);
to declare it,
func = &test::my_default;
to assign it, and
(this->*func)(5);
to call it. Of course, now you can't make a member function pointer point to a lambda.
If on the other hand you want to bind this as the instance and create an ordinary function from a member function, well, you can't actually make an ordinary function pointer to it. Instead you'll want an std::function object,
std::function<void(int)> func;
bind as follows:
func = std::bind(&test::my_default, this, std::placeholders::_1);
and then call normally. std::function works with lambdas just like a function pointer would.
struct Widget {
void test() {}
};
int func() {}
int main() {
std::cout << &Widget::test << std::endl;
std::cout << Widget::test << std::endl;
std::cout << func << std::endl;
std::cout << &func << std::endl;
}
In this code only the second line of main function doesn't compile. The others print 1. Why does it print 1. Shouldn't print the address of function? And why second doesn't compile but first does?
Why does it print 1. Shouldn't print the address of function?
No. std::cout can print a void*, but there's no implicit conversion from function pointer types to void* (for neither regular function pointers nor pointer-to-member types). There's a conversion from function pointer types to bool though. That's what we end up with.
And why second doesn't compile but first does?
Because the standard requires you to use & to get the address of a member function.