I have the following piece of code.
class A {
public:
A(int) {
}
};
int a;
int main() {
A(a); // Line 'a
return 0;
}
What I want to do on line 'a is to create a temporary A
with constructor A::A(int)
. I know it's going to destruct immediately. That's what I want. But it seems the compiler is doing something equivalent to A a
, defining variable a
as of class A
and initialize it using constructor A::A()
. Of course it doesn't exist, hence the compiler error.
However, if I change my code to the following.
class A {
public:
A(int) {
}
};
void f(A) {
}
int a;
int main() {
f(A(a));
return 0;
}
It works fine now. The compiler constructs a temporary A
and use it to call f
.
Why is A(a)
different in both contexts? How is it stated in the standard or for some obscure reason? How can I construct a temporary object as in the first code sample?
Temporary objects are created by the optimizer in order to process a query. In general, these temporary objects are internal objects and cannot be accessed by a user.
A temporary object is an unnamed object created by the compiler to store a temporary value.
Explanation: The temporary object is not created. If object is returned by reference, a particular memory location will be denoted with another name and hence same address values will be used. 10.
Temporary objects are often created during execution of a C++ program. Result of C++ operators (unary, binary, logical, etc.) and return-by-value functions always give rise to temporary objects. For built-in types, the cost of creating temporaries is minimal because compilers often use CPU registers to manipulate them.
This is another instance of the "everything that can be a declaration is a declaration" rule. [stmt.ambig]/p1:
There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a
(
. In those cases the statement is a declaration.
The standard provides the following examples:
Assuming T is a simple-type-specifier,
T(a)->m = 7; // expression-statement T(a)++; // expression-statement T(a,5)<<c; // expression-statement T(*d)(int); // declaration T(e)[5]; // declaration T(f) = { 1, 2 }; // declaration T(*g)(double(3)); // declaration
In the last example above,
g
, which is a pointer toT
, is initialized todouble(3)
. This is of course ill-formed for semantic reasons, but that does not affect the syntactic analysis.
and also:
class T { // ... public: T(); T(int); T(int, int); }; T(a); // declaration T(*b)(); // declaration T(c)=7; // declaration T(d),e,f=3; // declaration extern int h; T(g)(h,2); // declaration
The simplest way to disambiguate is probably an extra set of parentheses. (A(a));
is unambiguously an expression-statement.
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