如何在C++中创建临时对象

Hot*_*PxL 15 c++

我有以下代码.

class A {
 public:
  A(int) {
  }
};

int a;
int main() {
  A(a);  // Line 'a
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我想在第一行做的是A用构造函数创建一个临时的A::A(int).我知道它会立即毁灭.这就是我想要的.但似乎编译器正在做一些等价的事情A a,a在类中定义变量A并使用构造函数初始化它A::A().当然它不存在,因此编译错误.

但是,如果我将我的代码更改为以下内容.

class A {
 public:
  A(int) {
  }
};

void f(A) {
}

int a;
int main() {
  f(A(a));
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

它现在工作正常.编译器构造一个临时的A并使用它来调用f.

为什么A(a)两种情况都不同?它是如何在标准中或出于某些模糊的原因陈述的?如何在第一个代码示例中构造临时对象?

T.C*_*.C. 20

这是"一切可以作为声明是宣言"规则的另一个例子.[stmt.ambig]/P1:

在涉及表达式语句和声明的语法中存在歧义:具有函数式显式类型转换(5.2.3)的表达式语句,因为其最左侧的子表达式与第一个声明 符以a开头的声明无法区分.在这些情况下,该声明是一个声明.(

该标准提供以下示例:

假设T是一个简单类型说明符,

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
Run Code Online (Sandbox Code Playgroud)

在上面的最后一个例子中g,它是一个指针T,被初始化为double(3).由于语义原因,这当然是不正确的,但这并不影响句法分析.

并且:

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
Run Code Online (Sandbox Code Playgroud)

消除歧义的最简单方法可能是一组额外的括号.(A(a));毫无疑问是表达式陈述.


Vin*_*ert 5

我想不出一种方法来创建一个临时文件而不在某些调用中使用它,就像您对函数所做的那样。

为什么不想创建一个命名变量呢?鉴于您尝试声明它的方式,它的生命周期将与您的“临时”完全相同。

如果你真的想控制你的对象的销毁,你总是可以将它封装在一个块中: { A tmp(a); } // temporary A object


问题是……我看不出这样做的意义。为什么要创建一个临时对象而不使用它?这通常意味着您的对象创建或销毁有一些您想要触发的副作用。这真是一个糟糕的主意!您应该将副作用移动到一个函数并简单地调用它。