ошибка: запрошено преобразование из 'main()::<lambda()>' в нескалярный тип 'function<void()>'

В следующем фрагменте я пытаюсь преобразовать лямбду в свой собственный объект-функцию, ограничивая его концепцией, основанной на свойстве типа invocable_r. Однако gcc отвергает это.

Демо

      #include <concepts>
#include <cstdio>


template <typename Fn, typename R, typename... Args>
concept invocable_r = std::is_invocable_r<R, Fn, Args...>::value;

template <typename R, typename... Args>
class function
{
    template <invocable_r<R, Args...> Cb>
    function(Cb fn) {
        printf("Converting constructor invoked!\n");
    }

};

int main()
{
    function<void()> hello = [](){};
}

Ошибка:

      error: conversion from 'main()::<lambda()>' to non-scalar type 'function<void()>' requested

Кажется, я не могу найти проблему. В чем дело?

1 ответ

Вы определили шаблонfunctionнеправильный. Ваша версия принимает несколько аргументов, при инфаркте вы хотите иметь один аргумент определенного типа.

Вам нужно использовать специализацию шаблона. Также вы забыли оpublic::

      #include <concepts>
#include <cstdio>


template <typename Fn, typename R, typename... Args>
concept invocable_r = std::is_invocable_r<R, Fn, Args...>::value;

template <typename T>
class function;

template <typename R, typename... Args>
class function<R(Args...)>
{
public:
    template <invocable_r<R, Args...> Cb>
    function(Cb fn) {
        printf("Copy constructor invoked!\n");
    }

};

int main()
{
    function<void()> hello = [](){};
}

https://godbolt.org/z/xrvr3sMj3

Ваша версия должна использоваться следующим образом:

      int main()
{
    function<void> hello = [](){};
}

https://godbolt.org/z/xvGd1s4az

Кстати, есть концепция std::invocable , так что вы ввели что-то, что уже покрывается std.

Другие вопросы по тегам