Как убедиться, что автоматические параметры лямбды имеют один и тот же тип?

#c #lambda #c 14

Вопрос:

Если у меня есть лямбда-функция

 auto foo = [](auto amp;amp; a, auto amp;amp; b){ /* some random c   code */ };
 

Как я могу объявить, что a и b должны быть одного и того же типа, даже если этот тип может быть любым типом?

Комментарии:

1. Если вы хотите остановить компиляцию, когда типы a и b отличаются, почему бы не добавить static_assert(std::is_same_v<std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >); в качестве первой строки какой-нибудь случайный код C ?

2. auto foo = [](autoamp;amp; a, decltype(a) b) {};

Ответ №1:

Вы можете добавить a static_assert в тело лямбды:

 #include <type_traits>

auto foo = [](auto amp;amp; a, auto amp;amp; b){
    static_assert(std::is_same<typename std::remove_reference<decltype(a)>::type,
            typename std::remove_reference<decltype(b)>::type>::value, 
            "Must be of the same type!");
};
 

Возможно , вам захочется настроить типы для создания экземпляров std::is_same , например, не учитывать const — или volatile квалификаторы при сравнении и т. Д. (подумайте об std::decay этом ). Но обратите внимание, что могут возникнуть такие проблемы, как следующие:

 foo("abc", "de"); // fails to compile
 

поскольку выводимый тип здесь представляет собой массив символов, а не const char* .

Ответ №2:

Я знаю, что он помечен C 14, но вот решение C 20 на всякий случай:

 auto foo = []<typename T>(T amp;amp; a, T amp;amp; b){ /* some random c   code */ };
 

Комментарии:

1. Хорошее введение в шаблон лямбда для c 20 bfilipek.com/2020/08/lambda-generic.html