Почему концепция std::invocable блокирует компиляцию этого кода
Я не понимаю, почему ни лямбда, ни функция не распознаются как std::invocable
совместимые типы в следующем коде:
#include <concepts>
#include <iostream>
void f( std::invocable auto callback)
{
callback(47);
}
void function_callback(int i)
{
std::cout << i << std::endl;
}
auto lambda_callback = [](int i )
{
std::cout << i << std::endl;
};
int main(int)
{
f(&function_callback);
f(lambda_callback);
}
Я использую ствол GCC с -std=c++2a
флаг включен.
1 ответ
Решение
Если вы посмотрите на определение invocable
(или в стандарте):
template< class F, class... Args >
concept invocable =
requires(F&& f, Args&&... args) {
std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
/* not required to be equality preserving */
};
Что это значит:
void f( std::invocable auto callback)
И будет понятнее, если мы напишем его в полной форме:
template <typename F>
requires std::invocable<F>
void f(F callback);
В том, что F
вызывается без аргументов - это нулевая функция (Args...
здесь пустая упаковка). Ни ваша функция, ни ваша лямбда не являются нулевыми функциями - они обе унарны, поэтому ограничение правильно их отклоняет.
Вероятно, вы хотите:
void f( std::invocable<int> auto callback)
который проверяет, если callback
вызывается с одним аргументом типа int
.