Почему это не неприятный разбор?

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

А вот в коме онлайн меня просто утомило следующее.

class T{

public:

    T(int i){
    }

    int fun1(){
        return 1;
    }

};

int main()
{
    T myT(10); // I thought it'd be a function declaration that takes an int and returns a type T
    myT.fun1(); // and a compiler error out here.
} 

Но компилируется нормально и ошибок нет. Я просмотрел стандартные документы, но не смог прийти к рассуждениям.

Итак, что мне здесь не хватает?


person liaK    schedule 08.05.2011    source источник
comment
почему вы ожидаете другого, вы правильно создаете экземпляр T   -  person Nim    schedule 08.05.2011


Ответы (3)


10 не может быть именем типа параметра, поэтому это должно быть объявление переменной.

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

person Bo Persson    schedule 08.05.2011

Потому что 10 не является типом. :)

Это был бы самый неприятный разбор:

T myT(T());
// T() gets interpreted as function pointer argument to a function returning T();
// This is equivalent to:
T myT(T (*fn)());

Еще одна разновидность Most Vexing Parse:

unsigned char c = 42;
T myT(int(c));
// int(c) gets interpreted as an int argument called c.
// This is equivalent to:
T myT(int c);
person Boaz Yaniv    schedule 08.05.2011

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

T myT(T());

Как в этом полном примере:

#include <iostream>

struct T { int f() { return 1; } };

int main(int argc, char** argv) {
    T t(T());
    std::cout << t.f() << '\n';
    return 0;
}

Что неоднозначно, потому что это может означать:

  • myT — это T, инициализированный T, созданным по умолчанию; или же
  • myT — это функция, возвращающая T и принимающая один аргумент типа T(), что означает функцию без аргументов, возвращаемый тип которой также T.

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

См. статью Википедии об этом.

person Jon Purdy    schedule 08.05.2011