Можем ли мы смешивать ограниченный auto
заполнитель в качестве типа возвращаемого значения без конца и типа возвращаемого значения в конце?
Демо
template<class T>
concept C = sizeof(T) > sizeof(char);
C auto g1(auto) -> int { return 1; }
C auto g2(auto) -> char { return '2'; }
int main() {
return g1(0) + g2(0);
}
- GCC и MSVC: хорошо, возвращает
1 + '2'
, даже еслиg2
возвращаетchar
- Clang: ошибка с
function with trailing return type must specify return type 'auto', not 'C auto'
Я ожидал, что
Concept auto foo(auto a, auto b) -> decltype(a + b)
{ return a + b; }
эквивалентно
auto foo(auto a, auto b) -> decltype(a + b)
requires Concept<decltype(a + b)>
{ return a + b; }
Решение проблемы
Они не эквивалентны. Прежде всего правильно:
auto foo(auto a, auto b) -> Concept decltype(a + b) // or Concept auto
{ return a + b; }
он определяет функцию foo, которая возвращает тип decltype(a + b)
, ограниченный параметром Concept
. Если это невозможно, вы получите ошибку времени компиляции.
Другой:
auto foo(auto a, auto b) -> decltype(a + b)
requires Concept<decltype(a + b)>
{ return a + b; }
вернет тип decltype(a + b)
, но эта ФУНКЦИЯ (не тип повторной настройки) ограничена, чтобы быть действительной, только если decltype(a + b)
выполняет Concept
, поэтому, если это не так, вы не получите никаких ошибок, поскольку эта функция вообще не может использоваться из-за оговорка требует.
Что касается части вопроса «Смешивание»: с помощью C auto g1(auto) -> int { return 1; }
вы говорите что-то вроде «g1 вернет некоторый выведенный тип (авто), который должен соответствовать концепции C, а затем вы говорите return int
. Это довольно странно. Поэтому вы говорите компилятору вывести тип, то вы явно говорите, какой тип вернуть.Я думаю, что это не имеет смысла...
Также стандартный стандарт говорит, что:
«Если декларатор функции включает тип возвращаемого значения ([dcl.fct]), этот тип возвращаемого значения определяет объявленный тип возвращаемого значения функции».
Я ничего не нахожу, если стандарт не разрешает C auto
в начале, но он явно определяет, что если у вас есть тип замыкающего возврата, то тип замыкающего возврата указывает возвращаемый тип, а не автоматический заполнитель.
Так что в GCC и MSVC это может быть ошибка, или они просто намеренно игнорируют это...
Комментариев нет:
Отправить комментарий