Какова цель объявления типа int (x); или int (x) = 10;

Если вы посмотрите на грамматику для *declarator*s in §8/4, вы заметите, что noptr-declarator можно записать как (ptr-declarator), то есть он может быть записан как (declarator-id ), который проверяет объявления, подобные тем, что указаны в заголовке. На самом деле этот код компилируется без проблем:

#include <iostream>
struct A{ int i;};
int (x) = 100;
A (a) = {2};
int main()
{
    std::cout << x << '\n';
    std::cout << a.i << '\n';
}

Но для чего нужны эти круглые скобки, когда указатель (на массив или на функцию) не участвует в объявлении?


person Mao    schedule 09.11.2014    source источник
comment
Предположительно потому, что для их запрета потребуется более сложная грамматика.   -  person Oliver Charlesworth    schedule 09.11.2014
comment
Это может быть объяснением. Я не думал об этом.   -  person Mao    schedule 09.11.2014
comment
Точно так же (42) является допустимым выражением, даже если скобки не нужны.   -  person Keith Thompson    schedule 10.11.2014


Ответы (2)


Тот факт, что это правило применимо в вашем случае, не является преднамеренным: в конечном итоге это результат простой грамматики. Нет никаких стимулов для запрета таких заявлений, как ваше, но есть серьезные препятствия для усложнения правил, особенно если они сами по себе сложны.

Короче говоря, если вы не хотите использовать этот излишне запутанный синтаксис, не делайте этого.
C ++ редко заставляет вас писать читаемый код.

Удивительно, но есть сценарии, в которых скобки могут спасти положение:

std::string foo();

namespace detail
{
    int foo(long); // Another foo

    struct Bar
    {
        friend std::string ::foo(); // Doesn't compile for obvious reasons.

        friend std::string (::foo)(); // Voilà!
    };
}
person Columbo    schedule 09.11.2014
comment
Не могли бы вы дать небольшое объяснение friend std::string (::foo)(); декларации? Что мы на самом деле заявили и почему? - person ; 17.04.2015
comment
@DmitryFucintv: объявление хочет объявить экземпляр foo, который объявлен в первой строке, как friend структуры Bar. Чтобы объявить функцию дружественной, вам нужно указать ее тип возвращаемого значения и аргументы. Но сказать friend std::string foo() не получится, поскольку для неквалифицированного использования этот foo скрыт «другим» foo. Таким образом, нужно квалифицировать foo глобальным квалификатором ::. Но это дает первую отображаемую форму, которая страдает двусмысленностью с обозначением (несуществующего) члена std::string. Пара скобок вокруг ::foo помогает избежать двусмысленности - person Marc van Leeuwen; 17.04.2015

Вы задаете неправильный вопрос. Правильный вопрос:

Какова цель запрета такого заявления?

Ответ: нет.

Итак, учитывая, что этот синтаксис разрешен как побочный эффект правил в другом месте, вы получите именно это.

person Lightness Races in Orbit    schedule 05.12.2014
comment
Одна из причин запретить такое объявление заключается в том, что в настоящее время оператор T(x); является объявлением переменной x типа T, а не функциональным выражением приведения x к типу T (сделано исключительно для его побочных эффектов), что и является похоже. - person jchl; 22.01.2018
comment
@jchl: сделано исключительно из-за его побочных эффектов Вот ваша проблема - person Lightness Races in Orbit; 22.01.2018