if constexpr в рекурсивной универсальной лямбде: другое поведение компилятора - PullRequest
0 голосов
/ 03 мая 2018

Следующий код успешно компилируется с g ++ 7.3.0 и не компилируется с clang ++ 6.0.0 (флаги компиляции -std=c++17 -Wall -Wextra -Werror -pedantic-errors):

auto foo = [](auto, auto... tail) {
    if constexpr (sizeof...(tail) > 0)
    {
        return foo(tail...);
    }
    else
    {
        return 42;
    }
};

int main()
{
}

clang ++ сообщение об ошибке компиляции:

ошибка: переменная 'foo', объявленная с выведенным типом 'auto', не может появиться в своем собственном инициализаторе

return foo(tail...);

Какое поведение соответствует стандарту в этом случае?

1 Ответ

0 голосов
/ 03 мая 2018

Clang вправе отклонить это в соответствии с [dcl.spec.auto] / 10 , начиная с C ++ 17.

Если требуется тип сущности с неопределенным типом заполнителя чтобы определить тип выражения, программа плохо сформирована.

Тип foo необходим для разрешения рекурсивного вызова (найти operator() и т. Д.). Нужно определить тип закрытия. Поскольку здесь выводится тип замыкания ... вы видите, куда он идет.

GCC может доказать, что не всегда невозможно обойти это, но в целом стандарт запрещает это.

...