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

"авто" не допускается в прототипе функции с Clang

Используя Clang 3.5, 3.6 или 3.7, с флагом std=c++1y следующий код не компилируется:

#include <iostream>
auto foo(auto bar) { return bar; }
int main() {
  std::cout << foo(5.0f) << std::endl;
}

Указанная ошибка:

ошибка: "авто" не разрешено в прототипе функции

У меня нет ошибок с помощью g++ 4.9. Является ли эта ошибка результатом, потому что Clang еще не выполнил эту функциональную функцию еще или это потому, что мне не разрешено это делать, и GCC каким-то образом разрешает это?

4b9b3361

Ответ 1

Как мы видим из сообщения по расписанию ISO С++: параметры decltype (auto) и отличная переадресация параметры автоматической настройки не-lambdas являются частью концепт lite и, следовательно, не в С++ 14:

clang верен в том смысле, что у нас пока нет параметров авто. Понятия lite могут принести их, но С++ 14 их не имеет.

Если мы используем флаг -pedantic с gcc, мы получаем следующее предупреждение:

warning: ISO C++ forbids use of 'auto' in parameter declaration [-Wpedantic]
  auto foo(auto bar) { return bar; }
           ^

Итак, это выглядит как расширение.

Как указывал dyp, polymorphic lambdas сделал его в С++ 14 и разрешил авто параметры, пример взятый из статьи:

// 'Identity' is a lambda that accepts an argument of any type and
// returns the value of its parameter.
auto Identity = [](auto a) { return a; };
int three = Identity(3);
char const* hello = Identity("hello");

Какая, кстати, та же функциональность, которую вы хотите реализовать в своем примере.

Ответ 2

Хотя ваш конкретный синтаксис не попадал на С++ 14, аналогичный вариант:

static auto foo = [](auto bar) { return bar; };

который выполняет в основном одно и то же.

Ответ 3

Вместо этого вы можете использовать шаблон:

template<class A>
A foo(A bar) { return bar; }

Авто разрешается только тогда, когда компилятор может выводить тип из контекста.

Ответ 4

Компилятор не может вывести тип из контекста.

Что не так с этим делать

template<typename Y>
Y foo(Y bar){return bar;}

и вы должны пройти bar по значению?

В вашем случае вы можете использовать синтаксис типа возвращаемого типа:

auto foo(auto bar) -> decltype(bar)