C++ access rvalue referenced object from non rvalue object [duplicate] - c++

This question already has answers here:
My attempt at value initialization is interpreted as a function declaration, and why doesn't A a(()); solve it?
(5 answers)
Closed 8 years ago.
This question may be sound stupid. I just want to make sure. And maybe that someone point me where this described in standard.
We cannot have rvalue referenced objects inside lvalue. Right?
struct A{int value;};
struct B{
B(A &&value) : a(std::forward<A>(value)){}
A&& a;
};
int main()
{
// allowed
B(A()).a;
// error
B b(A());
b.a;
return 0;
}
http://coliru.stacked-crooked.com/a/ea6bd617d421a8b8

B b(A()); declares a function (most vexing parse). You get a compiler error because b has no member a.
To fix the issue write B b{A()} instead.

Related

Can anyone tell me what's wrong with the code below down? [duplicate]

This question already has an answer here:
Most vexing parse
(1 answer)
Closed 9 years ago.
Consider this code:
#include<iostream>
using namespace std;
class A
{
public:
A():age(12){}
int age;
};
int main()
{
A a();
cout << a.age << endl;
return 0;
}
When I compile it using g++, I get an error:
you can not see the member age, because a is not a class A()
Can someone explain this to me? What is A a()?
This line
A a();
declares a function named a, returning A with no arguments. (See Most vexing parse).
What you want is
A a = A(); // value-initialization
A a{}; // the same but only valid in C++11 (and currently not supported by MSVS)
or
A a; // default initialization
C++11, §8.5/10
Note: Since () is not permitted by the syntax for initializer,
X a();
is not the declaration of a value-initialized object of class X, but the declaration of a function taking no argument and returning an X.
For your class, value-initialization == default-initialization (at least for the outcome).
See my answer here: C++: initialization of int variables by an implicit constructor for Infos on value- vs. default-initialization for POD or built-in types.
It defines a function called a that returns an object of type A. This is known as the "most vexing parse".

Why is this variable considered an lvalue? [duplicate]

This question already has answers here:
Why are rvalues references variables not rvalue?
(3 answers)
Rvalue Reference is Treated as an Lvalue?
(4 answers)
Closed 3 years ago.
Considering this code
class T {
public:
T(T& x) = delete;
T(T&& x) {}
};
void foo(T&& b) {
T y(b);
}
I was expecting that b; which is an rvalue by declaration; and seemingly usage, should be passed into the move constructor of T in foo().
Instead; I get a compilation error reporting that T& has been deleted.
Replacing it with
void foo(T&& c) {
T y(std::move(c));
}
Results in the expected success; but obviously one doesn't want to litter their code with std::move everywhere.
As tempting as it is to blame visual studio - in this case I suspect it's my understanding that's wrong. Can someone please explain why move constructor isn't used?

why c++ class initialisation from another class type not throwing an error? [duplicate]

This question already has answers here:
Most vexing parse
(1 answer)
C++'s most vexing parse again [duplicate]
(2 answers)
Why does this class object declaration work?
(3 answers)
Closed 3 years ago.
I was expecting an error to be thrown by compiler for initializing a c++ type from a temporary variable of another type.
template <bool>
struct A{
A(...);
};
template <> struct A<false>{
};
class B{
};
class C{
int i;
};
int main()
{
//A a;
B b;
C c(B());
A<false> aa(B());
cout << "Hello World!!" << endl;
}
Here I have specialized class A for nontype parameter of type bool and value false, so that it has compiler generated standard constructors only, which should not accept any other type as initializing parameter.
For simplification I have used class C with same result(no error in compilation).
But if I do
C c(b);
it results in error which I expect: error: no matching function for call to ‘C::C(B&)’
You have encountered the most vexing parse. This
C c(B());
is the declaration of a function named c that returns a C object and has one parameter (not given a name, even though with optional parentheses) of type B. You have already a fix, C c(b), but note that initialization with curly braces helps, too:
C c{B{}}; // error
Note that it recent version of gcc and clang provide incredibly useful diagnostics, clang++ e.g. without any specific warnings flags remarks that
warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
C c(B());
^~~~~

Function Overloading with const [duplicate]

This question already has answers here:
Why is this call to member function ambiguous?
(3 answers)
Closed 5 years ago.
struct A
{
void fn(double a) const {}
void fn(int a){}
};
int main()
{
A().fn(1.);
}
For the above mentioned function why does the compiler produce an ambiguity; Both the types are different.
Why would you like to pass an int only to a non-const A?
There are two parameters to each member function, this and a. So you require a const A* for this and doublefor a, or non-const A* and int.
And the call doesn't fully match either alternative, as you have non-const Aand double. So the compiler can either convert A() to const A, or doubleto int. And it cannot decide which is the best.

What does A a() mean? [duplicate]

This question already has an answer here:
Most vexing parse
(1 answer)
Closed 9 years ago.
Consider this code:
#include<iostream>
using namespace std;
class A
{
public:
A():age(12){}
int age;
};
int main()
{
A a();
cout << a.age << endl;
return 0;
}
When I compile it using g++, I get an error:
you can not see the member age, because a is not a class A()
Can someone explain this to me? What is A a()?
This line
A a();
declares a function named a, returning A with no arguments. (See Most vexing parse).
What you want is
A a = A(); // value-initialization
A a{}; // the same but only valid in C++11 (and currently not supported by MSVS)
or
A a; // default initialization
C++11, §8.5/10
Note: Since () is not permitted by the syntax for initializer,
X a();
is not the declaration of a value-initialized object of class X, but the declaration of a function taking no argument and returning an X.
For your class, value-initialization == default-initialization (at least for the outcome).
See my answer here: C++: initialization of int variables by an implicit constructor for Infos on value- vs. default-initialization for POD or built-in types.
It defines a function called a that returns an object of type A. This is known as the "most vexing parse".