2015-09-06 2 views
2

Это очень простой вопрос о C++. Почему конструктор не вызывается для выражения «A x (A())»?Почему конструктор A не вызывается для выражения «A x (A())»?

В следующем коде, который я выполнил с g ++ 4.8.2, конструктор (а также деструктор) вызывается только один раз. Это может быть связано с оптимизацией, но мне интересно узнать тип x, о котором сообщает typeid - «A (A (*)())».

#include <iostream> 
#include <typeinfo> 
#include <cxxabi.h> 
using namespace std; 

class A{ 
public: 
~A() { cout << "Destructed" << endl; } 
}; 

int main() { 
    int status; 

    A x(A()); 
    cout << abi::__cxa_demangle(typeid(x).name(),0,0,&status) << endl; 

    A a ; 
    cout << abi::__cxa_demangle(typeid(a).name(),0,0,&status) << endl; 

    return 0; 
} 
+4

Используйте 'A x (A {});' или 'A x {A()};' или 'A x {A {}};' или 'A x ((A()));' –

+0

@ πάνταῥεῖ что * копия *? –

ответ

3

Это широко известный как C++ досадно синтаксический анализ, а это значит, что почти все, что может быть проанализировано как объявление функции будут.

Таким образом, A x(A()); действительно является объявлением функции, которое принимает в качестве своего параметра указатель функции типа A(), а тип возврата - A.

Вы можете добавить пару скобок, чтобы заставить компилятор обработать его в качестве инициализации переменной:

A x((A())); 

Потому что это не законно, чтобы окружить формальную декларацию параметров со скобками, но это законно окружать аргумент для вызова функции с круглыми скобками, поэтому, добавляя пару круглых скобок, мы вынуждаем компиляторы видеть вещи по-своему.

+0

Большое спасибо. Моя голова бегала по кругу. – argmin

Смежные вопросы