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)); // declarationIn 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