Am bit confused on the below code. `
class sample
{
public:
sample() { }
sample( sample& Obj ) { }
};
void fun( sample& Obj ) { }
int main()
{
sample s(sample());
fun( sample() );
return 0;
}
am getting the below error
Compilation failed due to following error(s). main.cpp: In function 'int main()': main.cpp:29:19: error: invalid initialization of non-const reference of type 'sample&' from an rvalue of type 'sample' fun( sample() );
I understood changing the argument in fun from sample& obj to const sample &obj will resolve the error.
My Question is, Even for copy constructor also, a temporary object has been send. But why compiler didn't throw the same error.
Nice explanation are most welcome
Regards Prasath S.
This line:
sample s(sample());
Is a declaration of a function called s that returns a sample object and takes as argument a function taking no arguments and returns a sample object. You're not calling the copy constructor at all. It's called "most vexing parse". Though some people object to that name.
You can see this is the case by writing to the console or putting a break point in the copy constructor, it will never be called. Another thing you will see is by adding a variable member to your class and trying to access it won't work. After the line:
sample s(sample());
Try to use:
s.sampleMember = 1;
And it will fail to compile on the grounds that s is a function declaration and not an object. There are a couple of ways to avoid this, you can surround the argument in another set of brackets:
sample s((sample()));
Or you can use C++11 onward style brace initialisation with something like:
sample s(sample{});
There are 2 problems here:
The one is "most vexing parse" problem in the line:
sample s(sample());
, like already mentioned. You are declaring function taking function with no argument as parameter and returning sample as value. Putting braces like sample s((sample())) or using new c++11 syntax sample s(sample{}) solves this problem.
The other one is that non-const lvalue reference cannot be bound to an rvalue, what your intent probably was in the line:
fun( sample() );
You have to declare fun argument to:
void fun( const sample& Obj ) { }
or (since c++11)
void fun( sample&& Obj ) { }
(assumed you dont want to change Obj within fun) then only const lvalue references or rvalue references can bind to rvalues. Otherwise if your intent is to change Obj within fun you have to leave the declaration non-const lvalue reference:
void fun(sample& Obj ) { }
and call it with some lvalue, like
fun(s)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With