简体   繁体   中英

How to create temporary object in C++

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?

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-statement s 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 to T , is initialized to double(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 .

I could not think of a way to create a temporary without using it in some call, like you did with the function.

Why don't you want to create a named variable instead? It's lifecycle will be exactly the same as your "temporary", given how you try to declare it.

If you really want to control the destruction of your object, you could always encapsulate it in a block: { A tmp(a); } // temporary A object { A tmp(a); } // temporary A object


The thing is... I don't see the point of doing that. Why would you want to create a temporary object without using it? It usually means that your object creation or destruction has some side effects that you want to trigger. This is a really bad idea! You should move the side effects to a function and simply call it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM