Невозможно полностью квалифицировать имя класса во внеклассовом деклараторе определения функции

Эта программа приводит к нежелательному тупику жадности синтаксического анализа:

struct float4x4 {};
class C
{
    float4x4 M();
};

float4x4 ::C::M()
{
    return float4x4{};
}

:8:1: ошибка: нет члена с именем 'C' в 'float4x4'; вы имели в виду просто 'C'?
float4x4 ::C::M()
^~~~~~~~~~~~~

Что можно «исправить» с помощью возвращаемого типа:

auto ::C::M() -> float4x4
{}

теперь все хорошо.

Я так понимаю, мы не можем полностью указать имя класса при использовании синтаксиса декларатора возвращаемого заголовка?


person v.oddou    schedule 18.11.2019    source источник
comment
Пока С++ игнорирует пробелы вокруг ::, я полагаю, что другого пути нет.   -  person Yksisarvinen    schedule 18.11.2019
comment
@Someprogrammerdude да, проверьте это godbolt.org/z/mt6GHD   -  person v.oddou    schedule 18.11.2019
comment
Часть ::C выглядит как обходной путь для какой-то другой проблемы. В противном случае это могло быть просто C (как предполагает компилятор;)   -  person rustyx    schedule 18.11.2019
comment
@rustyx это просто механическая повторная передача кода транспилером, который не хочет выполнять сверхсложный поиск наименее квалифицированного имени в этой позиции. выдача FQ-имени полностью обходит поиск и удобна для таких инструментов.   -  person v.oddou    schedule 18.11.2019


Ответы (1)


Вы можете поставить скобки для устранения неоднозначности:

float4x4 (::C::M)()
{
    return float4x4{};
}

Я не могу сказать вам, какое правило делает это нормальным, хотя и не без скобок, хотя я тестировал с помощью gcc и clang (оба -pedantic). Я бы предпочел возвращаемый тип.

person 463035818_is_not_a_number    schedule 18.11.2019
comment
невероятный. действительно можем. godbolt.org/z/KCFbJZ это отвратительно, но здорово. Конечно, с точки зрения стиля трейлинг великолепен. Но в моем случае я ориентируюсь на диалект, который его не поддерживает. - person v.oddou; 18.11.2019