2014-11-09 3 views
37

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

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

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

+13

Предположительно, потому что для их запрещения потребуется более сложная грамматика. –

+0

Это может быть объяснением. Я об этом не думал. – Mao

+2

Аналогично, '(42)' является допустимым выражением, даже если скобки не нужны. –

ответ

52

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

Короче говоря, если вы не хотите использовать этот бесполезно запутанный синтаксис, не делайте этого.
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à! 
    }; 
} 
+0

Не могли бы вы дать небольшое объяснение о 'friend std :: string (:: foo)();' declaration? Что мы действительно заявляли и почему? –

+3

@DmitryFucintv: объявление хочет объявить экземпляр 'foo', который объявлен в первой строке как« друг »структуры' Bar'. Чтобы объявить функцию другом, вам нужно указать ее тип и аргументы возврата. Но говоря «friend std :: string foo()' не будет работать, поскольку для неквалифицированного использования это 'foo' скрыто« другим »' foo'. Таким образом, нужно присвоить 'foo' глобальным классификатором' :: '. Но это дает первую отображаемую форму, которая страдает от двусмысленности с обозначением (несуществующего) элемента 'std :: string'. Пара круглых скобок вокруг ':: foo' служит для избежания двусмысленности –

4

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

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

Ответ: нет.

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

+1

Одна из причин отказа от такого объявления состоит в том, что в настоящее время оператор' T (x); 'является объявлением переменной' x' типа 'T' , а не функциональное выражение выражения 'x' для ввода' T' (сделано исключительно для его побочных эффектов), что и выглядит. – jchl

+0

@jchl: _ «сделано исключительно для его побочных эффектов» _ Есть ваша проблема –

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