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

时间:2015-05-13 08:50:43

标签: c++

我有以下代码。

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

int a;
int main() {
  A(a);  // Line 'a
  return 0;
}

我想在线'a'创建一个带有构造函数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;
}

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

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

2 个答案:

答案 0 :(得分:19)

这是&#34的另一个例子;所有可以作为声明的声明都是声明"规则。 [stmt.ambig] / P1:

  

涉及表达式语句的语法存在歧义   和声明:带有函数样式的表达式语句   显式类型转换(5.2.3),因为它最左边的子表达式可以   与第一个声明符声明无法区分   以(开头。在这些情况下,语句声明

该标准提供以下示例:

  

假设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
     

在上面的最后一个示例中,初始化了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

消除歧义的最简单方法可能是一组额外的括号。 (A(a));明确地是表达式语句

答案 1 :(得分:4)

我想不出一种方法来创建一个临时的,而不是在某个调用中使用它,就像你使用函数一样。

为什么不想创建命名变量呢?考虑到你如何宣告它,它的生命周期将与你的“临时”完全相同。

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

事情是......我没有看到这样做的重点。为什么要在不使用它的情况下创建临时对象?它通常意味着您的对象创建或销毁具有一些您想要触发的副作用。这是一个非常糟糕的主意!您应该将副作用移动到一个函数并简单地调用它。