"авто" не допускается в прототипе функции с 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 каким-то образом разрешает это?
Ответы
Ответ 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)