#include <iostream>
struct Box
{
Box() { std::cout << "constructor called" << std::endl; }
Box(const Box&) { std::cout << "Copy constructor called" << std::endl; }
Box(Box&&) { std::cout << "Move constructor called" << std::endl; }
void run() const { std::cout << "Run" << std::endl;}
};
int main()
{
Box a(Box());
a.run();
}
(demo)
In the above code I was expecting either Copy Constuctor
or Move Constructor
to be called on passing anonymous object Box()
as argument. But none of them were called. Reason probably might be copy elision
. But even constructor is not called for anonymous object A()
. Actually, the above code does not compile and on calling run()
function compiler gave following error.
a.cpp: In function ‘int main()’:
a.cpp:28:7: error: request for member ‘run’ in ‘a’, which is of non-class type ‘Box(Box (*)())’
a.run();
So when we type Box a(Box())
what is happening? What is being created?
An anonymous object is essentially a value that has no name. Because they have no name, there's no way to refer to them beyond the point where they are created. Consequently, they have “expression scope”, meaning they are created, evaluated, and destroyed all within a single expression.
Because passing by value to a function means the function has its own copy of the object. To this end, the copy constructor is called.
Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to explicitly define a type first. The type name is generated by the compiler and is not available at the source code level. The type of each property is inferred by the compiler.
Anonymous object in Java means creating an object without any reference variable. Generally, when creating an object in Java, you need to assign a name to the object. But the anonymous object in Java allows you to create an object without any name assigned to that object.
This is a case of the Most Vexing Parse. When something could be parsed as a function declaration, it is.
Box a(Box())
is the declaration of a function named a
taking a function of type Box (*)()
as argument and returning a Box
.
A solution is to use the (new in C++11) aggregate initialization for constructing your objects:
Box a{Box{}}
(demo)
The MVP is discussed in its simplest form in this stackoverflow question Most vexing parse: why doesn't A a(()); work?
If you do have an expression within then it is valid. For example:
((0));//compiles
To learn more about how languages are defined, and how compilers work, you should learn about Formal language theory or more specifically Context Free Grammars (CFG) and related material like finite state machines. If you are interested in that though the wikipedia pages won't be enough, you'll have to get a book.
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