Как использовать условие require с аргументами лямбда-функтора?

Есть ли способ применить общий запрос к аргументам лямбда-функтора?

Предположим, что у меня есть два ограничения C1 и C2, которые я хочу проверить против аргумента. Я ожидал, что следующее будет работать, поскольку для функций разрешен аналогичный синтаксис:

[](auto x) requires C1<decltype(x)> && C2<decltype(x)> {
    // ...
}

Но этот не будет компилироваться с GCC 6

Ответ 1

В моем скромном мнении и на основе Концепции TS §5.1.4/c4 Требуется выражение [expr.prim.req] (Акцент Мой):

Обязательное выражение должно появляться только в определении понятия (7.1.7) или в требовании-предложения декларации шаблона (Раздел 14) или объявление функции (8.3.5).

В приведенной выше цитате конкретно указаны контексты, в которых может появляться предложение requires, и lambdas не является одним из них.

Concequently,

[](auto x) requires C1<decltype(x)> && C2<decltype(x)> {
    // ...
}

Недействительно.

Однако в п. 5.1.2 Лямбда-выражения [expr.prim.lambda] есть следующий пример:

template<typename T> concept bool C = true;
auto gl = [](C& a, C* b) { a = *b; }; // OK: denotes a generic lambda

Итак, я думаю, вы могли бы выполнить то, что хотите, следующим образом:

template <class T> concept bool C1 = true;                                        
template <class T> concept bool C2 = true;
template <class T> concept bool C3 = C1<T> && C2<T>; // Define a concept that combines 
                                                     // `C1` and `C2` requirements.                   

int main() {                                                                      
  auto f = [](C3 x)  { /* Do what ever */ }; // OK generic lambda that requires input 
                                             // argument satisfy `C1` and `C2`                                                                                                                          
} 

Live Demo