В C ++ 11 есть ли способ шаблона лямбда-функции? Или это слишком специфично для шаблонов?
Я понимаю, что вместо этого я могу определить классический шаблонный класс / функтор, но вопрос больше похож на: позволяет ли язык шаблонизировать лямбда-функции?
Ответы:
ОБНОВЛЕНИЕ 2018: C ++ 20 будет поставляться с шаблонными и концептуальными лямбдами. Эта функция уже включена в стандартный черновик.
ОБНОВЛЕНИЕ 2014: C ++ 14 был выпущен в этом году и теперь предоставляет полиморфные лямбды с тем же синтаксисом, что и в этом примере. Некоторые крупные компиляторы уже реализуют это.
На это стоит (в C ++ 11), к сожалению, нет. Полиморфные лямбды были бы превосходны с точки зрения гибкости и мощности.
Первоначальная причина, по которой они оказались мономорфными, заключалась в концепциях. Концепции усложнили ситуацию с кодом:
В ограниченном шаблоне вы можете вызывать только другие ограниченные шаблоны. (В противном случае ограничения не могут быть проверены.) Может
foo
вызватьbar(x)
? Какие ограничения есть у лямбды (в конце концов, для нее это просто шаблон)?Концепции не были готовы решать подобные вещи; это потребовало бы большего количества вещей, таких как
late_check
(где концепция не проверялась до тех пор, пока не было вызвано) и прочее. Проще было просто бросить все это и придерживаться мономорфных лямбд.Однако с удалением понятий из C ++ 0x полиморфные лямбды снова становятся простым предложением. Однако я не могу найти никаких предложений для этого. :(
источник
decltype()
Лямбда C ++ 11 не может быть шаблонизирована, как указано в других ответах, но, кажется, помогает при использовании лямбды в шаблонном классе или функции.Печать:
Я обнаружил, что этот метод помогает при работе с шаблонным кодом, но понимает, что он все еще означает, что сами лямбды не могут быть шаблонизированы.
источник
T
будет хорошо работать вместо этогоdecltype(t)
в этом примере.В C ++ 11 лямбда-функции не могут быть шаблонизированы, но в следующей версии стандарта ISO C ++ (часто называемой C ++ 14) эта функция будет представлена. [Источник]
Пример использования:
Обратите внимание, что хотя в синтаксисе используется ключевое слово
auto
, для вывода типа не будут использоваться правилаauto
вывода типов, а вместо этого будут использоваться правила вывода аргументов шаблона. Также см. Предложение для общих лямбда-выражений (и обновление к этому).источник
auto
вывода типа специально определены так же, как правила выводаtemplate
аргумента функции.Я знаю, что этот вопрос о C ++ 11. Однако для тех, кто погуглил и приземлился на этой странице, шаблонные лямбды теперь поддерживаются в C ++ 14 и носят название Generic Lambdas.
[info] Большинство популярных компиляторов поддерживают эту функцию сейчас. Microsoft Visual Studio 2015 поддерживает. Clang поддерживает. GCC поддерживает.
источник
Интересно, что по этому поводу:
Я использовал подобный код, подобный этому, чтобы сгенерировать шаблон и задаться вопросом, оптимизирует ли компилятор функцию «обертывания».
источник
Взгляните на Boost.Phoenix для полиморфных лямбд: http://www.boost.org/doc/libs/1_44_0/libs/spirit/phoenix/doc/html/index.html Не требует C ++ 0x, согласно путь :)
источник
Существует расширение gcc, которое позволяет использовать лямбда-шаблоны :
где
_widgets
находитсяstd::tuple< fusion::pair<Key_T, Widget_T>... >
источник
Я играл с последней
version 5.0.1
компиляцией clang с-std=c++17
флагом, и теперь есть хорошая поддержка параметров автоматического типа для лямбд:источник
Вот одно решение, которое включает в себя упаковку ламбы в структуру:
Чтобы использовать сделать:
Основная проблема с этим (помимо дополнительной типизации) - вы не можете встроить это определение структуры в другой метод или получите (gcc 4.9)
Я также попытался сделать это:
С надеждой, что я смогу использовать это так:
Но я получаю ошибку компилятора:
Так что это не работает ... но даже если бы он действительно компилировался, он имел бы ограниченное использование, потому что нам все равно пришлось бы помещать "using LamdaT" в область видимости файла (потому что это шаблон), что в некотором роде противоречит цели лямбды.
источник
Я не уверен, почему никто другой не предложил это, но вы можете написать шаблонную функцию, которая возвращает лямбда-функции. Следующее решило мою проблему, причина, по которой я пришел на эту страницу:
Теперь, когда я хочу функцию, которая принимает аргумент данного типа (например
std::string
), я просто говорюа теперь
f("any string")
возвращается1.0
.Это пример того, что я подразумеваю под «шаблонной лямбда-функцией». (Этот конкретный случай используется для автоматического предоставления инертной весовой функции, когда кто-то не хочет взвешивать свои данные, какими бы они ни были.)
источник