Подтвердить что ты не робот

В С++, имеет ли область с именованным параметром выражение для значения по умолчанию?

Пример: Является ли это законным С++ 14?

#include <iostream>
static int d() {
    return 42;
}
static int e(int d = d()) {
    return d;
}
int main() {
    std::cout << e() << " " << e(-1) << std::endl;
}

g++ 5.4 с -std=c++14 ему нравится, но clang++ 3.8 с -std=c++14 жалуется:

samename.cxx:3:23: error: called object type 'int' is not a function or function pointer
static int e(int d = d()) {return d;}
                     ~^
4b9b3361

Ответ 1

Из basic.scope.pdecl/1:

Точка объявления для имени сразу после завершения декларатором и перед его инициализатором (если есть), за исключением случаев, указанных ниже.

Пример:

unsigned char x = 12;
{ unsigned char x = x; }

Здесь второй x инициализируется со своим (неопределенным) значением.

Clang согласуется с этим разделом стандарта. Кажется, что GCC применяет его в {block}.

Дано:

constexpr int d() {return 42;}

В Clang не выполняется следующее, но работает в GCC:

static int e(int d = d()) {return d;}
             // This ^^d should refer to the new name that shadows ::d()

В Clang и GCC происходит следующее:

void func(){
    int d = d();
         // ^^d here refers to the new name that shadowed ::d();
 }

Ответ 2

Кажется, что это не является законным: см. спецификацию С++ 14 (раздел 3.3.2 - Точка декларации).

int x = 5;
{ int x = x; } // second x is initialized with its own undetermined state
{ int x[x]; }  // declares an array with 5 elements, since the declaration of 
               // second x is not complete when the first x is used

В вашем случае объявление d завершено, поэтому, когда вы используете d(), вы ссылаетесь на переменную, а не на функцию.