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.
Related
I am not sure I understand why the first test evaluates to true and the second to false. I know that the information from typeid().name() is usually not reliable, but my main problem is with the typeid itself. I don't understand why the type of *test is not Location<1>, or what else is wrong. Any thoughts? Is there same wrapper around a type here that I don't see? Thanks in advance, and apologies if the answer is obvious.
#include <iostream>
#include <utility>
#include <typeinfo>
class LocationAbstract
{
virtual void get_() = 0;
};
template<int i>
class Location : public LocationAbstract
{
public:
static constexpr int test = i;
virtual void get_() override
{
return;
}
};
template <int i>
Location<i> LocationGenerator()
{
Location<i> test{};
return test;
}
int main()
{
LocationAbstract *table[10];
table[0] = new decltype(LocationGenerator<0>());
table[1] = new decltype(LocationGenerator<1>());
Location<1> *test;
try
{
std::cout << "Casting\n";
test = dynamic_cast<Location<1>*>(table[1]);
}
catch (std::bad_cast &e)
{
std::cout << "Bad cast\n";
}
// test1, evaluates to true
std::cout << (typeid(*test) == typeid(*dynamic_cast<Location<1>*>(table[1]))) << "\n";
std::cout << typeid(*test).name() << "\n";
std::cout << typeid(*dynamic_cast<Location<1>*>(table[1])).name() << "\n----\n";
// test2, why does this evaluate to false while the above evaluates to true ?
std::cout << (typeid(Location<1>()) == typeid(*dynamic_cast<Location<1>*>(table[1]))) << "\n";
std::cout << typeid((Location<1>())).name() << "\n";
std::cout << typeid(*dynamic_cast<Location<1>*>(table[1])).name() << "\n";
auto test1 = Location<1>();
auto test2 = *dynamic_cast<Location<1>*>(table[1]);
std::cout << typeid(test1).name() << " and " << typeid(test2).name() << "\n";
return 0;
}
An extra set of () makes all the difference here. In typeid(Location<1>()) and typeid((Location<1>())), Location<1>() actually means two totally different things.
In typeid(Location<1>()), Location<1>() is interpreted as a function type that returns a Location<1> and takes no parameters.
In typeid((Location<1>())), Location<1>() is interpreted as value-initializing an anonymous Location<1> object.
The typeid operator can work on either types or expressions. That is, you can say typeid(int) as well as typeid(42). Since Location<1>() can be interpreted as a type, the language does so. (Location<1>()) cannot be interpreted as a type though, so it must be interpreted as an expression. The only thing Location<1>() can mean as part of an expression is to value-initialize an anonymous Location<1> object, so typeid gives you the type of that object.
Let this be yet another reason to prefer uniform-initialization syntax when creating temporary objects; Location<1>{} would not have this ambiguity.
Examine these two lines:
std::cout << (typeid(Location<1>()) == typeid(*dynamic_cast<Location<1>*>(table[1]))) << "\n";
std::cout << typeid((Location<1>())).name() << "\n";
In the first line, you use typeid(Location<1>()). typeid can take types as well as expressions, and Location<1>() is a function type with no parameters and a return type of Location<1>.
So why does the name print the same? That's because of the second line: typeid((Location<1>())). By wrapping the argument in parentheses, it is no longer a valid type, so it is treated as an expression and the name of typeid(Location<1>) is printed. Removing the extra parentheses prints F8LocationILi1EEvE under the same mangling scheme.
To avoid the ambiguity, you can also use the type directly (typeid(Location<1>)) or use braces: typeid(Location<1>{})).
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"
I've got a function that takes a void pointer as a parameter. I want to pass this function a pointer to a struct, and then access the values of that struct within the function.
//the struct
struct s{
int val;
};
//the function tries to access the object
int callback(void* p_obj)
{
//try creating a new struct based on p_obj
s2 = *(struct s*)p_obj;
std::cout << "VALUE IN CALLBACK: ";
std::cout << s2.val << std::endl; //prints a big-ass int
return 0;
}
//main calls the function
int main()
{
s s1;
s1.val = 42;
void* p1 = &s;
//show some output
std::cout << "s1.val: ";
std:cout << s1.val << std::endl; //prints 42
//std::cout << "p1->val: ";
//std:cout << *(struct s*)p1->val << std::endl; //does not compile
s p2 = *(struct s*)p1;
std::cout << "p2.val: ";
std:cout << p2.val << std::endl; //prints 42
//call the function
callback(&p1);
return 0;
}
I would expect the output in the callback function to be
VALUE IN CALLBACK: 42
VALUE IN CALLBACK: 42
but, instead, I think it's printing a memory address
VALUE IN CALLBACK:1989685088
VALUE IN CALLBACK:1989685088
Trying to access the members of a void pointer directly results in an error.
int callback(void* p_obj)
{
std::cout << "VALUE IN CALLBACK: ";
std::cout << (struct s*)p_obj->val << std::endl;
}
error: 'void*' is not a pointer-to-object type
Why is this? How can I access the members of a struct that a void* is pointing to?
EDIT: Fixed some typos in the writeup
You have two errors:
*(struct s)p_obj needs to be *(struct s*)p_obj, as p_obj is not a structure object.
Because of operator precedence the expression (struct s*)p_obj->val is actually equal to (struct s*)(p_obj->val). Which means you try to dereference the void* pointer and cast the member val to struct s*.
You should do ((struct s*)p_obj)->val to cast the pointer p_obj.
And more typos: *void p_obj is very much wrong, it should be void* p_obj. Please take care to copy-paste your minimal, complete, and reproducible example, not retype is as that might add extra errors not in your real code, which distracts from the actual errors and problems.
I would like to use lambdas to conditionally expand the functionality of a function within a class. There is no problem doing this outside of the class scope (see example), but the minimal working example below leads to a segmentation fault when calling a function that has modified itself within the class. Can anyone explain why this code fails and how I should be thinking about lambdas within a class differently than lambdas outside of a class?
#include <functional>
#include <iostream>
class MyClass
{
public:
MyClass(bool modify);
int a;
std::function<void (void)> myFunc;
};
MyClass::MyClass(bool modify)
{
a = 2;
myFunc = [this](){ std::cout << "1. Inside my initialized function; a="
<< this->a << std::endl;};
//myFunc(); -- works with or without being commented
if (modify)
{
myFunc = [this](){ this->myFunc();
std::cout << "2. adding an output line to my "
<< "initialized function" << std::endl;};
//EDIT: Originally tried
// myFunc = [myFunc](){ myFunc(); std::cout << endl; };
// but this will not compile. See edit of post below
//myFunc(); -- fails with or without being commented
}
}
int main(int argc, char **argv)
{
std::function<void (void)> func;
int a = 2;
func = [a](){ std::cout << "1. Inside my initialized function; a="
<< a << std::endl;};
func = [func](){ func();
std::cout << "2. adding an output line to my initialized "
<< "function" << std::endl;};
std::cout << "Result of modified function outside of class: " << std::endl;
func();
std::cout << std::endl;
std::cout << "Result of unmodified function in class: " << std::endl;
MyClass myClassNoMod(false);
myClassNoMod.myFunc();
std::cout << std::endl;
std::cout << "Result of modified function in class: " << std::endl;
MyClass myClassMod(true);
myClassMod.myFunc();
return 0;
}
Edit PaulR gave the reasonable suggestion of capturing myFunc rather than this in the update of myFunc. In my original implementation this is what I tried:
myFunc = [myFunc](){myFunc(); std::out << "stuff\n"; };
but this lead to the compiler errors
error: 'myFunc' in capture list does not name a variable
myFunc = [myFunc](){ myFunc();
^
error: 'this' cannot be implicitly captured in this context
myFunc = [myFunc](){ myFunc();
In your class you capture the this pointer and not the previous value of myFunc, thus your lambda will recursively call itself forever, since at call time the myFunc member will be already changed to the new lambda.
In main you capture the previous value of func by value and thus it does what you expect.
So I would suggest capturing a copy of myFunc by value (i.e. without &) instead of this.
if (modify)
{
auto previousFunc = std::move(myFunc);
myFunc = [previousFunc](){ previousFunc();
std::cout << "2. adding an output line to my "
<< "initialized function" << std::endl;};
}
If you are using C++14 or newer you can also use lambda capture expressions to avoid making a copy and directly moving the previous function into the lambda capture:
if (modify)
{
myFunc = [previousFunc{std::move(myFunc)}](){ previousFunc();
std::cout << "2. adding an output line to my "
<< "initialized function" << std::endl;};
}
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.