Тип возвращаемого значения лямбды может быть выведен по возвращаемому значению, так почему же функция не может?
#include <iostream>
int main(){
auto lambda = [] {
return 7;
};
std::cout << lambda() << '\n';
}
Эта программа компилирует и печатает 7.
Тип возврата лямбда выводится в целочисленный тип на основе возвращаемого значения 7.
Почему это невозможно с обычными функциями?
#include <iostream>
auto function(){
return 42;
}
int main(){
std::cout << function() << '\n';
}
ошибка: функция 'function' использует спецификатор типа 'auto' без завершающего типа возвращаемого значения
5 ответов
C++14 имеет эту функцию. Вы можете проверить это с новыми версиями GCC или Clang, установив -std=c++1y
флаг.
В дополнение к этому, в C++14 вы также можете использовать decltype(auto)
(который отражает decltype(auto)
как переменные) для вашей функции, чтобы вывести свое возвращаемое значение, используя decltype
семантика.
Примером может служить функция переадресации, для которой decltype(auto)
особенно полезно:
template<typename function_type, typename... arg_types>
decltype(auto) do_nothing_but_forward(function_type func, arg_types&&... args) {
return func(std::forward<arg_types>(args)...);
}
С использованием decltype(auto)
Вы имитируете фактический тип возврата func
при вызове с указанными аргументами. Больше нет дублирования кода в конце типа возврата, что очень печально и подвержено ошибкам в C++11.
Это всего лишь ограничение того, как язык создавался и развивался. В следующем стандарте C++14 возвращаемый тип функции может быть выведен в некоторых контекстах, но не во всех. Существуют сложности, когда есть несколько операторов возврата.
Кроме того, у выведенных типов возврата есть и другие проблемы, например, тип возврата функции шаблона нельзя использовать в контексте SFINAE, так как для возможности определения типа компилятор должен создать экземпляр шаблона функции, что происходит после подстановки. Конечным результатом является то, что, хотя эта функция появится в ближайшем будущем, я бы ее избегал, если бы вы могли предоставить тип самостоятельно.
Его еще нет... он будет в C++1y/C++14.. проверьте эту ссылку функции
Я предполагаю, что это, вероятно, потому что выведенные по типу лямбды не могут быть рекурсивными.
Почему это важно? Потому что если лямбда с выводом типа может быть рекурсивной (под "выводом типа" я подразумеваю, где имя переменной имеет тип auto
), тогда его возвращаемый тип потенциально может зависеть от самого себя - и хотя иногда это можно решить, его гораздо сложнее реализовать, чем "простой" вывод типа. Я даже не уверен, что это всегда разрешимо (это разрешимо в общем случае?). Если бы функции поддерживали вывод типов, тем не менее, об этой проблеме нужно было бы позаботиться, поэтому, вероятно, они просто исключили их по этой причине.