Получить сигнатуру из ламбды
От: Barbar1an Украина  
Дата: 12.08.20 07:37
Оценка:
если у нас


template<class L> Subscribe(L lambda)
{
    std::function<сигнатура вызова lambdы> f; // типа void(int, int)
    std::function<void(сигнатура параметров lambdы)> f; // типа только "int, int"
}

Subscribe([](int, int){});



возможно както?
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Отредактировано 12.08.2020 7:39 Barbar1an . Предыдущая версия .
Re: Получить сигнатуру из ламбды
От: Voivoid Россия  
Дата: 12.08.20 08:54
Оценка:
Здравствуйте, Barbar1an, Вы писали:

B>возможно както?


boost callable traits — https://www.boost.org/doc/libs/master/libs/callable_traits/doc/html/callable_traits/reference.html#callable_traits.reference.ref_function_type
Re[2]: Получить сигнатуру из ламбды
От: Barbar1an Украина  
Дата: 12.08.20 11:07
Оценка:
Здравствуйте, Voivoid, Вы писали:

V>Здравствуйте, Barbar1an, Вы писали:


B>>возможно както?


V>boost callable traits — https://www.boost.org/doc/libs/master/libs/callable_traits/doc/html/callable_traits/reference.html#callable_traits.reference.ref_function_type


а только std?
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re: Получить сигнатуру из ламбды
От: YuriV  
Дата: 12.08.20 14:42
Оценка:
Здравствуйте, Barbar1an, Вы писали:

B>если у нас


B>

B>template<class L> Subscribe(L lambda)
B>{
B>    std::function<сигнатура вызова lambdы> f; // типа void(int, int)
B>    std::function<void(сигнатура параметров lambdы)> f; // типа только "int, int"
B>}

B>Subscribe([](int, int){});
B>



B>возможно както?


namespace fn {

/**
 * \Note Function details description
 */
template<typename Sign, typename R, typename... Args>
struct traits_base {
  using signature = Sign;
  using is_method = std::is_member_function_pointer<signature>;
  using args = std::tuple<Args...>;
  using arity = std::integral_constant<unsigned, sizeof...(Args)>;
  using result = R;
};

/**
 * \Note Function details specializations
 */
template<typename T>
struct traits : traits<decltype(&T::operator())> {};
template<typename R, typename... Args>
struct traits<R(*)(Args...)> : traits_base<R(*)(Args...), R, Args...> {};
template<typename R, typename... Args>
struct traits<R(* const)(Args...)> : traits_base<R(* const)(Args...), R, Args...> {};
#if __cplusplus >= 201703
template<typename R, typename... Args>
struct traits<R(*)(Args...) noexcept> : traits_base<R(*)(Args...), R, Args...> {};
template<typename R, typename... Args>
struct traits<R(* const)(Args...) noexcept> : traits_base<R(* const)(Args...), R, Args...> {};
#endif // __cplusplus >= 201703
template<typename R, typename C, typename... Args>
struct traits<R(C::*)(Args...)> : traits_base<R(C::*)(Args...), R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::* const)(Args...)> : traits_base<R(C::* const)(Args...), R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::*)(Args...) const> : traits_base<R(C::*)(Args...) const, R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::* const)(Args...) const> : traits_base<R(C::* const)(Args...) const, R, Args...> {};
#if __cplusplus >= 201703
template<typename R, typename C, typename... Args>
struct traits<R(C::*)(Args...) noexcept> : traits_base<R(C::*)(Args...), R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::* const)(Args...) noexcept> : traits_base<R(C::* const)(Args...), R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::*)(Args...) const noexcept> : traits_base<R(C::*)(Args...) const, R, Args...> {};
template<typename R, typename C, typename... Args>
struct traits<R(C::* const)(Args...) const noexcept> : traits_base<R(C::* const)(Args...) const, R, Args...> {};
#endif // __cplusplus >= 201703

} // namespace fn

// use, e.g. std::function<typename fn::traits<L>::signature> f;


Список аргументов можно добыть через tuple<Args...> to parameter pack mapping. Здесь недостаёт recognition rules для function volatile qualifier только.
Отредактировано 12.08.2020 14:48 YuriV . Предыдущая версия .
Re: Получить сигнатуру из ламбды
От: _NN_ www.nemerleweb.com
Дата: 12.08.20 16:12
Оценка:
Здравствуйте, Barbar1an, Вы писали:

На всякий случай серия статей насколько это непросто разобрать указатель на функцию: https://devblogs.microsoft.com/oldnewthing/20200713-00/?p=103978
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Получить сигнатуру из ламбды
От: Barbar1an Украина  
Дата: 12.08.20 18:17
Оценка:
Здравствуйте, YuriV, Вы писали:

YV>// use, e.g. std::function<typename fn::traits<L>::signature> f;


YV>Список аргументов можно добыть через tuple<Args...> to parameter pack mapping. Здесь недостаёт recognition rules для function volatile qualifier только.


я попробовал signature и args но оба говорят что

error C3520: 'L': parameter pack must be expanded in this context
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re: Получить сигнатуру из ламбды
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 12.08.20 18:25
Оценка:
Здравствуйте, Barbar1an, Вы писали:


B>возможно както?



А decltype() какой-нибудь?
Маньяк Робокряк колесит по городу
Re[2]: Получить сигнатуру из ламбды
От: Barbar1an Украина  
Дата: 12.08.20 18:27
Оценка:
Здравствуйте, YuriV, Вы писали:

вот так хочу заюзать

    template<class ...A> struct CActiveDelegate
    {
        CDelegate<void(A...)>        Function;
        std::function<void(A...)>    Lambda;
        EListen                Listen;

        CActiveDelegate()
        {
        }
    };

    template<class X, class Y, typename...A> CActiveDelegate<A...> CreateActiveDelegate(Y* x, void (X::*func)(A...), EListen l)
    { 
        CActiveDelegate<A...> d;
        d.Function = fastdelegate<void(A...)>(x, func);
        d.Listen = l;
        return d;
    }


    template<class ...L> CActiveDelegate<typename fn::traits<L>::args> CreateLambdaDelegate(L la, EListen l)
    { 
        CActiveDelegate<typename fn::traits<L>::args> d;
        d.Lambda = la;
        d.Listen = l;
        return d;
    }

    #define FunctionSubscriber(method, l)    CreateActiveDelegate(this, &std::remove_pointer<decltype(this)>::type::method, l)
    #define LambdaSubscriber(la, l)        CreateLambdaDelegate(la, l)

    template<class ...A> class CActiveEvent
    {
        public:
            void operator += (CActiveDelegate<A...> & d)
            {
                Subscribers.push_back(d);
            }

        protected:
            CArray<CActiveDelegate<A...>>    Subscribers;
    };


    class A
    {
        void AAA(CString &)
        {
            CActiveEvent<CString &> aaa;

            aaa += FunctionSubscriber(AAA, EListen::NormalAll);
            aaa += LambdaSubscriber([](CString &){}, EListen::NormalAll);

        }
    };
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Отредактировано 12.08.2020 18:29 Barbar1an . Предыдущая версия .
Re[2]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 12.08.20 19:18
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, Barbar1an, Вы писали:


_NN>На всякий случай серия статей насколько это непросто разобрать указатель на функцию:


Годы шли, а крестоговнари так и не добавили в язык рефлексию.
Re[3]: Получить сигнатуру из ламбды
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.08.20 00:08
Оценка: +1 :))
Здравствуйте, T4r4sB, Вы писали:

_NN>>На всякий случай серия статей насколько это непросто разобрать указатель на функцию:


TB>Годы шли, а крестоговнари так и не добавили в язык рефлексию.


Годы шли, стандарты плюсов расширялись и дополнялись, расширялись и дополнялись, а говнокодеры так и не удосужились изучить что-то новое для себя. Особо говнистые живут в 0x03ем году, и только выступать и умеют
Маньяк Робокряк колесит по городу
Re[3]: Получить сигнатуру из ламбды
От: YuriV  
Дата: 13.08.20 07:39
Оценка:
Здравствуйте, Barbar1an, Вы писали:

B>Здравствуйте, YuriV, Вы писали:


B>вот так хочу заюзать


B>
B>    template<class ...L> CActiveDelegate<typename fn::traits<L>::args> CreateLambdaDelegate(L la, EListen l)
B>    { 
B>        CActiveDelegate<typename fn::traits<L>::args> d;
B>        d.Lambda = la;
B>        d.Listen = l;
B>        return d;
B>    }
B>


Во-первых праметер-пак(class ...L) не нужен. Что ожидает в качестве темплейт-параметра CActiveDelegate? Если сигнатуру функции (как fastdelegate), то попробуй:
template<class L> auto CreateLambdaDelegate(L la, EListen l) -> CActiveDelegate<typename fn::traits<L>::signature> {...}
Re[4]: Получить сигнатуру из ламбды
От: Barbar1an Украина  
Дата: 13.08.20 08:06
Оценка:
Здравствуйте, YuriV, Вы писали:

YV>Во-первых праметер-пак(class ...L) не нужен.


точно, это я перестарался

YV>Что ожидает в качестве темплейт-параметра CActiveDelegate?


вообще там долден быть пак аргументов, но я поменял всё на сигнатуру

    template<typename S> struct CActiveDelegate
    {
        fastdelegate::FastDelegate<S>    Function;
        std::function<S>        Lambda;
        int                Listen;

        CActiveDelegate()
        {
        }
    };

    template<class X, class Y, typename...A> auto CreateActiveDelegate(Y* x, void (X::*func)(A...), int l)
    { 
        CActiveDelegate<void(A...)> d;
        d.Function = fastdelegate::FastDelegate<void(A...)>(x, func);
        d.Listen = l;
        return d;
    }


    template<class L> auto CreateLambdaDelegate(L la, int l)
    { 
        CActiveDelegate<typename fn::traits<L>::signature> d;
        d.Lambda = la;
        d.Listen = l;
        return d;
    }

    #define FunctionSubscriber(method, l)    CreateActiveDelegate(this, &std::remove_pointer<decltype(this)>::type::method, l)
    #define LambdaSubscriber(la, l)            CreateLambdaDelegate(la, l)

    template<class ...A> class CActiveEvent
    {
        public:
            void operator += (CActiveDelegate<void(A...)> & d)
            {
                Subscribers.push_back(d);
            }

        protected:
            std::list<CActiveDelegate<void(A...)>>    Subscribers;
    };


    class A
    {
        void AAA(std::string &)
        {
            CActiveEvent<std::string &> aaa;

            aaa += FunctionSubscriber(AAA, 1);
            aaa += LambdaSubscriber([](std::string &){}, 2);

        }
    };


и все равно не проходит

1>CActiveDelegate<void (__thiscall A::AAA::<lambda_65ea410b267bfdbc362c6e23c2be9649>::* )(std::string &) const>::Function' uses undefined class 'fastdelegate::FastDelegate<S>'

1> with
1> [
1> S=void (__thiscall A::AAA::<lambda_65ea410b267bfdbc362c6e23c2be9649>::* )(std::string &) const
1> ]

например потому что у нас сигнратура const какого-то хрена
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Отредактировано 13.08.2020 8:07 Barbar1an . Предыдущая версия .
Re[5]: Получить сигнатуру из ламбды
От: YuriV  
Дата: 13.08.20 09:24
Оценка:
Здравствуйте, Barbar1an, Вы писали:

B>Здравствуйте, YuriV, Вы писали:


YV>>Во-первых праметер-пак(class ...L) не нужен.


B>точно, это я перестарался


YV>>Что ожидает в качестве темплейт-параметра CActiveDelegate?


B>вообще там долден быть пак аргументов, но я поменял всё на сигнатуру


B>
B>    template<typename S> struct CActiveDelegate
B>    {
B>        fastdelegate::FastDelegate<S>    Function;
B>        std::function<S>        Lambda;
B>        int                Listen;

B>        CActiveDelegate()
B>        {
B>        }
B>    };

B>    template<class X, class Y, typename...A> auto CreateActiveDelegate(Y* x, void (X::*func)(A...), int l)
B>    { 
B>        CActiveDelegate<void(A...)> d;
B>        d.Function = fastdelegate::FastDelegate<void(A...)>(x, func);
B>        d.Listen = l;
B>        return d;
B>    }


B>    template<class L> auto CreateLambdaDelegate(L la, int l)
B>    { 
B>        CActiveDelegate<typename fn::traits<L>::signature> d;
B>        d.Lambda = la;
B>        d.Listen = l;
B>        return d;
B>    }

B>    #define FunctionSubscriber(method, l)    CreateActiveDelegate(this, &std::remove_pointer<decltype(this)>::type::method, l)
B>    #define LambdaSubscriber(la, l)            CreateLambdaDelegate(la, l)

B>    template<class ...A> class CActiveEvent
B>    {
B>        public:
B>            void operator += (CActiveDelegate<void(A...)> & d)
B>            {
B>                Subscribers.push_back(d);
B>            }

B>        protected:
B>            std::list<CActiveDelegate<void(A...)>>    Subscribers;
B>    };


B>    class A
B>    {
B>        void AAA(std::string &)
B>        {
B>            CActiveEvent<std::string &> aaa;

B>            aaa += FunctionSubscriber(AAA, 1);
B>            aaa += LambdaSubscriber([](std::string &){}, 2);

B>        }
B>    };
B>


B>и все равно не проходит


1>>CActiveDelegate<void (__thiscall A::AAA::<lambda_65ea410b267bfdbc362c6e23c2be9649>::* )(std::string &) const>::Function' uses undefined class 'fastdelegate::FastDelegate<S>'

1>> with
1>> [
1>> S=void (__thiscall A::AAA::<lambda_65ea410b267bfdbc362c6e23c2be9649>::* )(std::string &) const
1>> ]

B>например потому что у нас сигнратура const какого-то хрена


Так компайлер ругается на fastdelegate, а не на CreateLambdaDelegate. Зачем тебе разделять лямбды и обычные функции/методы? Пихай всё в fastdelegate/std::function. Проверь код fastdelegate, там нет к-тора для const функторов видимо. Если нельзя добавить, то сними const std::remove_const/std::remove_cv. Последнее снимает и volatile qualifier. Попробуй закомментировать
aaa += FunctionSubscriber(AAA, 1);
и скомпилить. Я этим кодом пользуюсь лет 6 наверное.
Re[6]: Получить сигнатуру из ламбды
От: Barbar1an Украина  
Дата: 13.08.20 09:40
Оценка:
Здравствуйте, YuriV, Вы писали:

YV>Так компайлер ругается на fastdelegate, а не на CreateLambdaDelegate.


да, но это потому что в качестве S приходит чтото, что не похоже на сигнатуру

YV>Зачем тебе разделять лямбды и обычные функции/методы? Пихай всё в fastdelegate/std::function.


та я бы рад но у фастделегата нету лямбд, а в стд::функция не знаю как прикрутить фукнции так чтобы без лямбд было и без указания сигнатуры,
чтобы писать прсто ааa += FunctionSubscriber(AAA, 1) и всё без всяких биндов и лишних лямбд

YV>Проверь код fastdelegate, там нет к-тора для const функторов видимо. Если нельзя добавить, то сними const std::remove_const/std::remove_cv. Последнее снимает и volatile qualifier.


не помогло)

YV>Попробуй закомментировать
aaa += FunctionSubscriber(AAA, 1);
и скомпилить. Я этим кодом пользуюсь лет 6 наверное.


не компилит, а вот если лямбду закоментить то с fastdelegate всё ок
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[7]: Получить сигнатуру из ламбды
От: YuriV  
Дата: 13.08.20 09:59
Оценка:
Здравствуйте, Barbar1an, Вы писали:

B>Здравствуйте, YuriV, Вы писали:


YV>>Так компайлер ругается на fastdelegate, а не на CreateLambdaDelegate.


B>да, но это потому что в качестве S приходит чтото, что не похоже на сигнатуру


YV>>Зачем тебе разделять лямбды и обычные функции/методы? Пихай всё в fastdelegate/std::function.


B>та я бы рад но у фастделегата нету лямбд, а в стд::функция не знаю как прикрутить фукнции так чтобы без лямбд было и без указания сигнатуры,

B>чтобы писать прсто ааa += FunctionSubscriber(AAA, 1) и всё без всяких биндов и лишних лямбд

YV>>Проверь код fastdelegate, там нет к-тора для const функторов видимо. Если нельзя добавить, то сними const std::remove_const/std::remove_cv. Последнее снимает и volatile qualifier.


B>не помогло)


YV>>Попробуй закомментировать
aaa += FunctionSubscriber(AAA, 1);
и скомпилить. Я этим кодом пользуюсь лет 6 наверное.


B>не компилит, а вот если лямбду закоментить то с fastdelegate всё ок

Ну запости лог без
aaa += FunctionSubscriber(AAA, 1);
.
Re[8]: Получить сигнатуру из ламбды
От: Barbar1an Украина  
Дата: 13.08.20 10:03
Оценка:
Здравствуйте, YuriV, Вы писали:

YV>Ну запости лог без [ccode]aaa += FunctionSubscriber(AAA, 1);


  закоменчено //aaa += FunctionSubscriber(AAA, 1);
1>------ Build started: Project: Console, Configuration: Debug Win32 ------
1>Console.cpp
1>M:\Projects\Console\Console.cpp(59,33): error C2079: 'CActiveDelegate<std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>>::Function' uses undefined class 'fastdelegate::FastDelegate<S>'
1> with
1> [
1> S=std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>
1> ]
1>M:\Projects\Console\Console.cpp(79): message : see reference to class template instantiation 'CActiveDelegate<std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>>' being compiled
1>M:\Projects\Console\Console.cpp(137): message : see reference to function template instantiation 'auto CreateLambdaDelegate<A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>>(L,int)' being compiled
1> with
1> [
1> L=A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1093,19): error C2338: std::function does not accept non-function types as template arguments.
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1118): message : see reference to class template instantiation 'std::_Get_function_impl<_Fty>' being compiled
1> with
1> [
1> _Fty=std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>
1> ]
1>M:\Projects\Console\Console.cpp(60): message : see reference to class template instantiation 'std::function<S>' being compiled
1> with
1> [
1> S=std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1118,51): error C2039: 'type': is not a member of 'std::_Get_function_impl<_Fty>'
1> with
1> [
1> _Fty=std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1118): message : see declaration of 'std::_Get_function_impl<_Fty>'
1> with
1> [
1> _Fty=std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1118,56): error C2504: 'type': base class undefined
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1120,56): error C2039: 'type': is not a member of 'std::_Get_function_impl<_Fty>'
1> with
1> [
1> _Fty=std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1118): message : see declaration of 'std::_Get_function_impl<_Fty>'
1> with
1> [
1> _Fty=std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1120,1): error C2061: syntax error: identifier 'type'
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1132,1): error C2653: '_Mybase': is not a class or namespace name
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1132,1): error C4430: missing type specifier — int assumed. Note: C++ does not support default-int
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1153,1): error C2653: '_Mybase': is not a class or namespace name
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1153,1): error C4430: missing type specifier — int assumed. Note: C++ does not support default-int
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1187,1): error C2653: '_Mybase': is not a class or namespace name
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1187,1): error C4430: missing type specifier — int assumed. Note: C++ does not support default-int
1>M:\Projects\Console\Console.cpp(80,1): error C2679: binary '=': no operator found which takes a right-hand operand of type 'L' (or there is no acceptable conversion)
1> with
1> [
1> L=A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1203,15): message : could be 'std::function<S> &std::function<S>::operator =(std::nullptr_t) noexcept'
1> with
1> [
1> S=std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1178,15): message : or 'std::function<S> &std::function<S>::operator =(std::function<S> &&) noexcept'
1> with
1> [
1> S=std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\functional(1162,15): message : or 'std::function<S> &std::function<S>::operator =(const std::function<S> &)'
1> with
1> [
1> S=std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>
1> ]
1>M:\Projects\Console\Console.cpp(80,1): message : while trying to match the argument list '(std::function<S>, L)'
1> with
1> [
1> S=std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>
1> ]
1> and
1> [
1> L=A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>
1> ]
1>M:\Projects\Console\Console.cpp(137,1): error C2679: binary '+=': no operator found which takes a right-hand operand of type 'CActiveDelegate<std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>>' (or there is no acceptable conversion)
1>M:\Projects\Console\Console.cpp(91,9): message : could be 'void CActiveEvent<std::string &>::operator +=(CActiveDelegate<void (std::string &)> &)'
1>M:\Projects\Console\Console.cpp(137,1): message : while trying to match the argument list '(CActiveEvent<std::string &>, CActiveDelegate<std::remove_const<void (__thiscall A::AAA::<lambda_b40f81b86c19d3a041e4fe2a8702035f>::* )(std::string &) const>>)'
1>Done building project "Console.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[9]: Получить сигнатуру из ламбды
От: YuriV  
Дата: 13.08.20 13:16
Оценка: 6 (1) +1
Здравствуйте, Barbar1an, Вы писали:

У меня получилось только так там два варианта. В fn::traits_base добавь
using cpp11_signature = R(Args...);
и используй как
using sign = typename fn::traits<L>::cpp11_signature;
using fft = std::function<sign>;
event.lambda = fft(std::forward<L>(lambda));
...
.

ЗЫ: мсвц пиздец тормоз...
Отредактировано 13.08.2020 13:24 YuriV . Предыдущая версия . Еще …
Отредактировано 13.08.2020 13:23 YuriV . Предыдущая версия .
Отредактировано 13.08.2020 13:22 YuriV . Предыдущая версия .
Re[10]: Получить сигнатуру из ламбды
От: Barbar1an Украина  
Дата: 13.08.20 14:25
Оценка:
Здравствуйте, YuriV, Вы писали:

YV>Здравствуйте, Barbar1an, Вы писали:


YV>У меня получилось только так там два варианта. В fn::traits_base добавь
using cpp11_signature = R(Args...);
и используй как
YV>using sign = typename fn::traits<L>::cpp11_signature;
YV>using fft = std::function<sign>;
YV>event.lambda = fft(std::forward<L>(lambda));
YV>...
YV>
.


YV>ЗЫ: мсвц пиздец тормоз...


cpp11_signature — помогло пасиба)
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[4]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 13.08.20 20:01
Оценка: +2
Здравствуйте, Marty, Вы писали:

M>Годы шли, стандарты плюсов расширялись и дополнялись, расширялись и дополнялись, а говнокодеры так и не удосужились изучить что-то новое для себя. Особо говнистые живут в 0x03ем году, и только выступать и умеют


Что, добавили новую категорию объектов, из-за чего в класс вектора пришлось добавить ещё 5 видов конструкторов, и ещё 3 случая в метод реаллокации?
Re[5]: Получить сигнатуру из ламбды
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.08.20 22:38
Оценка:
Здравствуйте, T4r4sB, Вы писали:

M>>Годы шли, стандарты плюсов расширялись и дополнялись, расширялись и дополнялись, а говнокодеры так и не удосужились изучить что-то новое для себя. Особо говнистые живут в 0x03ем году, и только выступать и умеют


TB>Что, добавили новую категорию объектов, из-за чего в класс вектора пришлось добавить ещё 5 видов конструкторов, и ещё 3 случая в метод реаллокации?


Много чего добавили
Маньяк Робокряк колесит по городу
Re: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 14.08.20 07:15
Оценка:
Здравствуйте, Barbar1an, Вы писали:

B>если у нас

B>
B>template<class L> Subscribe(L lambda)
B>{
B>    std::function<сигнатура вызова lambdы> f; // типа void(int, int)
B>    std::function<void(сигнатура параметров lambdы)> f; // типа только "int, int"
B>}

B>Subscribe([](int, int){});
B>

B>возможно както?

Да в принципе, не сложно, если вспомнить, что все лямбды — это просто объекты классов с перегруженными operator(). Можно даже без концептов и SFINAE. И можно даже предоставить универсальную реализацию, которая будет применима не только к лямбдам, но и к обычным функциям, и к определенным пользователем классам функциональных объектов.

Ниже эскизная реализация. До полной реализации здесь не хватает поддержки 'const', 'volatile', '&', '&&', 'nothrow' и всех их комбинаций (это если требуется поддержка пользовательских классов функциональных объектов).

http://coliru.stacked-crooked.com/a/7c29edffdf60891a

#include <string>
#include <tuple>
#include <type_traits>

template <typename>
struct CallableTraits;

template <typename ReturnT, typename...ParamT>
struct CallableTraits<ReturnT(ParamT...)>
{
    static constexpr size_t Arity = sizeof...(ParamT);
    using Signature = ReturnT(ParamT...);
    using ReturnType = ReturnT;
    using ParameterTypes = std::tuple<ParamT...>;
};

template <typename ReturnT, typename...ParamT>
struct CallableTraits<ReturnT(*)(ParamT...)> : CallableTraits<ReturnT(ParamT...)> {};

template <typename T, typename ReturnT, typename...ParamT>
struct CallableTraits<ReturnT(T::*)(ParamT...)> : CallableTraits<ReturnT(ParamT...)> {};

template <typename T, typename ReturnT, typename...ParamT>
struct CallableTraits<ReturnT(T::*)(ParamT...) const> : CallableTraits<ReturnT(ParamT...)> {};

template <typename T>
struct CallableTraits : CallableTraits<decltype(&std::decay_t<T>::operator())> {};

template <typename T>
constexpr size_t CallableArity = CallableTraits<T>::Arity;

template <typename T>
using CallableSignature = typename CallableTraits<T>::Signature;

template <typename T>
using CallableReturnType = typename CallableTraits<T>::ReturnType;

template <typename T, size_t I>
using CallableParameterType = std::tuple_element_t<I, typename CallableTraits<T>::ParameterTypes>;

int main()
{
    int i = 42;

    auto lambda = [=](int, double, const std::string&) { return i; };

    using L = decltype(lambda);

    static_assert(CallableArity<L> == 3, "");
    static_assert(std::is_same_v<CallableSignature<L>, int(int, double, const std::string&)>, "");
    static_assert(std::is_same_v<CallableParameterType<L, 0>, int>, "");
    static_assert(std::is_same_v<CallableParameterType<L, 1>, double>, "");
    static_assert(std::is_same_v<CallableParameterType<L, 2>, const std::string&>, "");
    static_assert(std::is_same_v<CallableReturnType<L>, int>, "");
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 14.08.2020 7:26 rg45 . Предыдущая версия . Еще …
Отредактировано 14.08.2020 7:25 rg45 . Предыдущая версия .
Отредактировано 14.08.2020 7:24 rg45 . Предыдущая версия .
Отредактировано 14.08.2020 7:19 rg45 . Предыдущая версия .
Отредактировано 14.08.2020 7:17 rg45 . Предыдущая версия .
Re[5]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 14.08.20 07:27
Оценка: +1 -1
Здравствуйте, T4r4sB, Вы писали:

TB>Что, добавили новую категорию объектов, из-за чего в класс вектора пришлось добавить ещё 5 видов конструкторов, и ещё 3 случая в метод реаллокации?


Слушай, надоел ты уже своим нытьем. Иди в эвакуаторщики, если для тебя все так сложно.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[6]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 14.08.20 08:46
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>Слушай, надоел ты уже своим нытьем. Иди в эвакуаторщики, если для тебя все так сложно.


Даже-не-джуниор, который пишет в стиле "мамкин хацкер", и не понимает, почему другим это не нравится, будет меня учить?
Re[7]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 14.08.20 09:01
Оценка:
Здравствуйте, T4r4sB, Вы писали:


TB>Даже-не-джуниор, который пишет в стиле "мамкин хацкер", и не понимает, почему другим это не нравится, будет меня учить?


Тебе до моего стиля, расти и расти. Только учить тебя у меня никакого желания нет, ибо бесполезно. Просто нытье твое невежественное достало. В каждой теме одно и то же.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 14.08.2020 9:04 rg45 . Предыдущая версия .
Re[8]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 14.08.20 09:03
Оценка:
Здравствуйте, rg45, Вы писали:

R>Тебе до моего стиля, расти и расти.


Стиль "я крутой, потому что умею писать сложно"? Это уровень младших курсов, гуляй.
Re[9]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 14.08.20 09:08
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Стиль "я крутой, потому что умею писать сложно"?


Пресловутая "сложность" выдумана тобой и характеризует только тебя.

TB>Это уровень младших курсов, гуляй.


Когда я был на младших курсах, ты пешком под стол ходил, мой юный друг.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[10]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 14.08.20 09:17
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>Когда я был на младших курсах, ты пешком под стол ходил, мой юный друг.


Тебе что, 45 лет? Ну тогда респект за то, что в таком возрасте ты остался юн душою!
Re[11]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 14.08.20 09:20
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Тебе что, 45 лет?


Это ж пипец, и я еще о чем-то дискутирую с этим человеком

А я что, профиль на РСДН только в этом году завел? Или, может быть, ники каждый год меняю? Гигант мысли ты наш.

TB>Ну тогда респект за то, что в таком возрасте ты остался юн душою!


А, то есть, 45 лет — для тебя это "ТАКОЙ ВОЗРАСТ"? Я, вообще-то думал, что это тебе 45, ошибся походу
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 14.08.2020 10:09 rg45 . Предыдущая версия . Еще …
Отредактировано 14.08.2020 9:31 rg45 . Предыдущая версия .
Отредактировано 14.08.2020 9:27 rg45 . Предыдущая версия .
Отредактировано 14.08.2020 9:26 rg45 . Предыдущая версия .
Отредактировано 14.08.2020 9:24 rg45 . Предыдущая версия .
Re[2]: Получить сигнатуру из ламбды
От: Went  
Дата: 14.08.20 13:13
Оценка:
Здравствуйте, rg45.
А насколько можно быть увереным, что у лямбды не будет перегруженного оператора скобки? За исключением обобщенных лямбд, возможны отказы в подобной реализации трейтов?
Re[3]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 14.08.20 13:18
Оценка:
Здравствуйте, Went, Вы писали:

W>А насколько можно быть увереным, что у лямбды не будет перегруженного оператора скобки? За исключением обобщенных лямбд, возможны отказы в подобной реализации трейтов?


Признаться, никаких гарантий я найти не смог. Ни по поводу отсутствия дополнительных перегрузок, ни по поводу наличия единственного необходимого оператора. Так что здесь вся надежда на здравый смысл и результаты эксперимента на разных компиляторах. Ну в самом деле, что это может быть, если не operator() и каким образом может оказаться несколько перегрузок?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[12]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 14.08.20 19:31
Оценка:
Здравствуйте, rg45, Вы писали:

R>А, то есть, 45 лет — для тебя это "ТАКОЙ ВОЗРАСТ"?


Ну, для твоего уровня рассуждений — да, многовато...
Re[13]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 14.08.20 19:40
Оценка:
Здравствуйте, T4r4sB, Вы писали:

R>>А, то есть, 45 лет — для тебя это "ТАКОЙ ВОЗРАСТ"?


TB>Ну, для твоего уровня рассуждений — да, многовато...


Ну ты подрасти немного, сынок, потом поговорим.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[14]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 14.08.20 19:48
Оценка:
Здравствуйте, rg45, Вы писали:

R>Ну ты подрасти немного, сынок, потом поговорим.


Я вырос из "сложна эта крута", а ты нет.
Re[15]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 14.08.20 19:49
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Я вырос из "сложна эта крута", а ты нет.


Это нормально. Мне в твоем возрасте тоже казалось, что я вырос.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[16]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 14.08.20 20:32
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, T4r4sB, Вы писали:


TB>>Я вырос из "сложна эта крута", а ты нет.


R>Это нормально. Мне в твоем возрасте тоже казалось, что я вырос.


Ты даже какашками кидаешься так, будто 2006 это не твоя дата регистрации, а твоя дата рождения.
Re[9]: Получить сигнатуру из ламбды
От: lpd Черногория  
Дата: 14.08.20 20:40
Оценка: :))) :)))
Здравствуйте, T4r4sB, Вы писали:

TB>Стиль "я крутой, потому что умею писать сложно"? Это уровень младших курсов, гуляй.


Точно, я вообще подозреваю что rg45 — виндузятник. И такие приходят на форум программистов.
Запомните: C++ — это С++03, а именно С с классами. Остальной треш придумали графоманы.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Отредактировано 14.08.2020 20:41 lpd . Предыдущая версия .
Re[11]: Получить сигнатуру из ламбды
От: ollv СССР https://youtu.be/DQDoYs6wHoo
Дата: 15.08.20 02:04
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, rg45, Вы писали:


R>>Когда я был на младших курсах, ты пешком под стол ходил, мой юный друг.


TB>Тебе что, 45 лет? Ну тогда респект за то, что в таком возрасте ты остался юн душою!

Дам совет. На фото rg45 одет в обычное ХБ. По всей видимости это повседневка, такую в мою бытность уже носили только для черновых работ, т/е служил он точно раньше 89-го года.

И да — меня тоже раздражает, когда кто-то мыслит так как ты. Если написано сложно, то так писать нельзя. Сложно, иногда — необходимость, и сршенно все равно, может понять это кто-то, или нет. (Вон квантовую механику никто не понимает, главный лозунг — считай и не думай (не помню, кто там кому об этом говорил))
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Re[10]: Получить сигнатуру из ламбды
От: ollv СССР https://youtu.be/DQDoYs6wHoo
Дата: 15.08.20 02:12
Оценка:
Здравствуйте, lpd, Вы писали:

lpd>Здравствуйте, T4r4sB, Вы писали:


TB>>Стиль "я крутой, потому что умею писать сложно"? Это уровень младших курсов, гуляй.


lpd>Точно, я вообще подозреваю что rg45 — виндузятник. И такие приходят на форум программистов.

lpd>Запомните: C++ — это С++03, а именно С с классами. Остальной треш придумали графоманы.
Ого )) сильно заявление. Каким образом стандарт С++ привязан к платформе ? Виндузятник/линуксовик это вообще важно в контексте С++ ..
Думаешь от количества платформ, под которые ты разрабатываешь меняется уровень осознания когда и возможностей ? Вот сейчас имею четыре разные платформы разработки мак / винда / айос / линукс и прочие фрибзди, а задачи и проект все равно — г. А вот под винду, иногда, приходилось уух знатно покодить (архитектурно с компайлтайм рефлекшинами мега хаками) мало кто понимал тот код. Всего двое, но только эти двое и могли писать в этом сегменте, своего рода защита от,... тех кому может не понравиться такой код.
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Re[10]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 15.08.20 05:50
Оценка:
Здравствуйте, lpd, Вы писали:

lpd>Точно, я вообще подозреваю что rg45 — виндузятник.


Оп-па! Козыри пошли
Действительно, что может знать о C++ какой-то виндузятник.
Прямо по Жванецкому

lpd>И такие приходят на форум программистов.


Ну я, по крайней мере, попытался дать вариант решения. А вот с какой целью ты приходишь? По-видимому, обсуждать мою личность — это максимум твоих возможностей.

lpd>Запомните: C++ — это С++03, а именно С с классами. Остальной треш придумали графоманы.


Ты к кому обращаешься сейчас? Кто должен запомнить, и почему твое невежество того стоит?
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 15.08.2020 6:14 rg45 . Предыдущая версия . Еще …
Отредактировано 15.08.2020 6:13 rg45 . Предыдущая версия .
Отредактировано 15.08.2020 6:12 rg45 . Предыдущая версия .
Re[17]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 15.08.20 05:52
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Ты даже какашками кидаешься так, будто 2006 это не твоя дата регистрации, а твоя дата рождения.


Ты самостоятельно нашел несоответствие между реальностью и своими ощущениями? Поздравляю. Ты на пути к выздоровлению.

У меня только одна маленькая просьба к тебе: постарайся ныть поменьше, ладно?

  Скрытый текст
Ну в самом деле, человек задает конкретный вопрос, можешь помочь — замечательно. Не можешь — ну просто почитай, что пишут другие. Пройди мимо, наконец. А кому интересны вот эти стоны — как все сложно и какие все плохие
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 15.08.2020 7:19 rg45 . Предыдущая версия . Еще …
Отредактировано 15.08.2020 7:16 rg45 . Предыдущая версия .
Отредактировано 15.08.2020 7:15 rg45 . Предыдущая версия .
Отредактировано 15.08.2020 7:11 rg45 . Предыдущая версия .
Отредактировано 15.08.2020 6:04 rg45 . Предыдущая версия .
Отредактировано 15.08.2020 6:03 rg45 . Предыдущая версия .
Отредактировано 15.08.2020 6:00 rg45 . Предыдущая версия .
Re[4]: Получить сигнатуру из ламбды
От: _NN_ www.nemerleweb.com
Дата: 15.08.20 09:00
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, Went, Вы писали:


W>>А насколько можно быть увереным, что у лямбды не будет перегруженного оператора скобки? За исключением обобщенных лямбд, возможны отказы в подобной реализации трейтов?


R>Признаться, никаких гарантий я найти не смог. Ни по поводу отсутствия дополнительных перегрузок, ни по поводу наличия единственного необходимого оператора. Так что здесь вся надежда на здравый смысл и результаты эксперимента на разных компиляторах. Ну в самом деле, что это может быть, если не operator() и каким образом может оказаться несколько перегрузок?


7.5.5 lambda-expressionis a prvalue whose result object is called theclosure object. [Note: A closure objectbehaves like a function object 

7.5.5.1  Closure types[expr.prim.lambda.closure]1
The type of alambda-expression(which is also the type of the closure object) is a unique, unnamed non-unionclass type, called theclosure type, whose properties are described below.


Есть гарантия, что это класс с операцией вызова "operator()".
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[12]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 15.08.20 10:09
Оценка:
Здравствуйте, ollv, Вы писали:


O>И да — меня тоже раздражает, когда кто-то мыслит так как ты. Если написано сложно, то так писать нельзя. Сложно, иногда — необходимость, и сршенно все равно, может понять это кто-то, или нет.


Иногда сложность вызвана кулхацкерскими амбициями, иногда — идиотским дизайном языка. В этих случаях необходимости нет.
Re[5]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 15.08.20 11:07
Оценка: +1
Здравствуйте, _NN_, Вы писали:

_NN>
_NN>7.5.5 lambda-expressionis a prvalue whose result object is called theclosure object. [Note: A closure objectbehaves like a function object 

_NN>7.5.5.1  Closure types[expr.prim.lambda.closure]1
_NN>The type of alambda-expression(which is also the type of the closure object) is a unique, unnamed non-unionclass type, called theclosure type, whose properties are described below.
_NN>


_NN>Есть гарантия, что это класс с операцией вызова "operator()".


Ну вот если бы где-нибудь упоминался явно "operator()", это развеяло бы все мои сомнения, но этого же нет. 'like a function object', как я это понимаю, означает, что доступно выражение вида: f(). А вот доступно ли выражение вида f.operator()() ? В это хочется верить, конечно, и эксперименты это подтверждают, но... остается некоторая неудовлетворенность.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[6]: Получить сигнатуру из ламбды
От: _NN_ www.nemerleweb.com
Дата: 15.08.20 13:14
Оценка: 6 (1) :)
Здравствуйте, rg45, Вы писали:

R>Ну вот если бы где-нибудь упоминался явно "operator()", это развеяло бы все мои сомнения, но этого же нет. 'like a function object', как я это понимаю, означает, что доступно выражение вида: f(). А вот доступно ли выражение вида f.operator()() ? В это хочется верить, конечно, и эксперименты это подтверждают, но... остается некоторая неудовлетворенность.


В 7.5.5.1 12

The lambda-expression’scompound-statement yields thefunction-body(9.5) of the function call operator,


https://eel.is/c++draft/expr.prim.lambda.closure#12

Оно?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[7]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 15.08.20 14:31
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>В 7.5.5.1 12

_NN>

_NN>The lambda-expression’scompound-statement yields thefunction-body(9.5) of the function call operator,


_NN>Оно?


Да хз, может и оно.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[13]: Получить сигнатуру из ламбды
От: ollv СССР https://youtu.be/DQDoYs6wHoo
Дата: 16.08.20 01:09
Оценка: +1
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, ollv, Вы писали:



O>>И да — меня тоже раздражает, когда кто-то мыслит так как ты. Если написано сложно, то так писать нельзя. Сложно, иногда — необходимость, и сршенно все равно, может понять это кто-то, или нет.


TB>Иногда сложность вызвана кулхацкерскими амбициями, иногда — идиотским дизайном языка.

Давай выражаться конкретно, что тебе конкретно не нравится в том, что трейтсы в С++ с шаблонами и классами выглядят именно так.
Что ты предложил бы в замен (да в рамках реально работающего компилятора С++) ? НЕ нравится С++ в целом — никто не заставляет. НЕ нравятся шаблоны — предложи как лучше распарсить сигнатуру в компайлтайм. Вот это против всего плохого за все хорошее — не тот топик.

TB>В этих случаях необходимости нет.

Как это нет ? Нет необходимости парсить сигнатуру? Молодец
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Re[14]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 16.08.20 09:09
Оценка: :))
Здравствуйте, ollv, Вы писали:

O> Давай выражаться конкретно, что тебе конкретно не нравится в том, что трейтсы в С++ с шаблонами и классами выглядят именно так.

O>Что ты предложил бы в замен (да в рамках реально работающего компилятора С++) ?

Я бы предложил расстрелять комитет для начала. И добавить в язык ключевые слова, которые бы прямо возвращали параметры сигнатуры.
Re[15]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 16.08.20 13:01
Оценка: +1 -1
Здравствуйте, T4r4sB, Вы писали:

TB>Я бы предложил расстрелять комитет для начала. И добавить в язык ключевые слова, которые бы прямо возвращали параметры сигнатуры.


--
Не можешь достичь желаемого — пожелай достигнутого.
Re[15]: Получить сигнатуру из ламбды
От: ollv СССР https://youtu.be/DQDoYs6wHoo
Дата: 17.08.20 12:11
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, ollv, Вы писали:


O>> Давай выражаться конкретно, что тебе конкретно не нравится в том, что трейтсы в С++ с шаблонами и классами выглядят именно так.

O>>Что ты предложил бы в замен (да в рамках реально работающего компилятора С++) ?

TB>Я бы предложил расстрелять комитет для начала. И добавить в язык ключевые слова, которые бы прямо возвращали параметры сигнатуры.

В каком виде ?
Даже нет
Вот давай
template <typename... Args>
inline some_return_type fun(Args... args);
typedef GET_TYPE_BASED_SIGN_MACRO(fun(5, std::string(), float(), char()) sign_type;

ну и давай получим к примеру тип 3-го аргумента
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Отредактировано 17.08.2020 12:23 Маркуша Шулин . Предыдущая версия .
Re[16]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 17.08.20 18:45
Оценка:
Здравствуйте, ollv, Вы писали:

O> В каком виде ?


Ключевое слово, параметр — указатель на функцию или функциональный тип, или тип с оператором (), возвращающее тип.
Я не знаю, что такое GET_TYPE_BASED_SIGN_MACRO
Re[17]: Получить сигнатуру из ламбды
От: ollv СССР https://youtu.be/DQDoYs6wHoo
Дата: 18.08.20 07:15
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, ollv, Вы писали:


O>> В каком виде ?


TB>Ключевое слово, параметр — указатель на функцию или функциональный тип, или тип с оператором (), возвращающее тип.

Погоди — давай код, как бы ты хотел, чтобы оно выглядело. Задача есть — берешь сигнатуру и получаешь тип третьего параметра. как это делается на плюсах мы примерно все знаем.
Там много парсить и много кейсов, но принцип понятен . Давай покажи нам свое предложение. Что значит ключевое слово ?

так typedef TYPE_OF_3_PARAMETER(func(int(), int(), int(), int())) third_parameter_type; ?


TB>Я не знаю, что такое GET_TYPE_BASED_SIGN_MACRO

переименуй как хочешь я же тебе именно это предлагаю.
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Re[2]: Получить сигнатуру из ламбды
От: Went  
Дата: 18.08.20 09:06
Оценка:
Здравствуйте, rg45.
Блин, когда 101% времени сидишь за прикладным кодом, голова вообще отказывается работать в направлении шаблонов
Пишу в рамках С++11. Хочу сделать функцию, которая принимает произвольный вызываемый объект (без учета возвратного значения), и возвращает функтор с подобной сигнатурой, но этот функтор не вызывает исходный объект, а лишь ставит его в очередь сообщений, прибиндивая к нему те параметры, с которыми был вызван этот функтор. По-моему, это что-то похожее на async.
Что-то такое:
void add_message_in_queue(const std::function<void()>&); // Эта функция ставит в очередь произвольный функтор без аргументов и возвратного значения.

// Эта функция должна взять произвольный функтор без возвратного значения, но с любым набором аргументов, и создать функтор с аргументами, который будет класть этот функтор в очередь, прибиндив аргументы
template<typename T>
auto defer(const T& fnc) -> typename std::function<typename stdext::call_traits<T>::signature> // stdext::call_traits<T> - это твои трейты, только в нижнем регистре :)
{
  std::function<typename stdext::call_traits<T>::signature> result = [fnc](???) // Вот что записать тут?
  {
    add_message_in_queue(???); // И тут
  };

  return result;
}

void main()
{
  auto x = [](int, float){};
  auto y = defer(x);

  y(1, 1.0f); // Должен не вызвать реализацию x, а положить его в очередь, прибиндив единицы как аргументы вызова к x.
}
Re[3]: Получить сигнатуру из ламбды
От: ollv СССР https://youtu.be/DQDoYs6wHoo
Дата: 18.08.20 09:15
Оценка: 4 (1)
Здравствуйте, Went, Вы писали:

W>Здравствуйте, rg45.

W>Блин, когда 101% времени сидишь за прикладным кодом, голова вообще отказывается работать в направлении шаблонов
W>Пишу в рамках С++11. Хочу сделать функцию, которая принимает произвольный вызываемый объект (без учета возвратного значения), и возвращает функтор с подобной сигнатурой, но этот функтор не вызывает исходный объект, а лишь ставит его в очередь сообщений, прибиндивая к нему те параметры, с которыми был вызван этот функтор. По-моему, это что-то похожее на async.
  Скрытый текст
W>Что-то такое:
W>
W>void add_message_in_queue(const std::function<void()>&); // Эта функция ставит в очередь произвольный функтор без аргументов и возвратного значения.

W>// Эта функция должна взять произвольный функтор без возвратного значения, но с любым набором аргументов, и создать функтор с аргументами, который будет класть этот функтор в очередь, прибиндив аргументы
W>template<typename T>
W>auto defer(const T& fnc) -> typename std::function<typename stdext::call_traits<T>::signature> // stdext::call_traits<T> - это твои трейты, только в нижнем регистре :)
W>{
W>  std::function<typename stdext::call_traits<T>::signature> result = [fnc](???) // Вот что записать тут?
W>  {
W>    add_message_in_queue(???); // И тут
W>  };
W>  return result;
W>

W>void main()
W>{
W>  auto x = [](int, float){};
W>  auto y = defer(x);

W>  y(1, 1.0f); // Должен не вызвать реализацию x, а положить его в очередь, прибиндив единицы как аргументы вызова к x.
W>}

W>



так чтобы по быстрому. можно выдрать из сигнатуры тупл и т/к это локальная лямбда, в смысле не влияет на внешний интерфейс ? если да, то
    typedef typename convert_2args_type<typename stdext::call_traits<T>::signature>::type args_tuple_type;
    std::function<typename stdext::call_traits<T>::signature> result = [fnc](args_tuple_type const& args)
     {
            // Здесь форейч по всем аргументам и в конце итерации вызов непосредственно функции 
        call_func_add_message_in_queue<0>(args);
        
     };

если же у тебя внешний интерфейс и локальная типизация извне не видна можно пихать в некий абстрактнфй тип вроде boost::any кастить перед вызовом.
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Отредактировано 18.08.2020 9:22 Маркуша Шулин . Предыдущая версия . Еще …
Отредактировано 18.08.2020 9:19 Маркуша Шулин . Предыдущая версия .
Отредактировано 18.08.2020 9:18 Маркуша Шулин . Предыдущая версия .
Re[3]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 18.08.20 09:25
Оценка:
Здравствуйте, Went, Вы писали:

W>Здравствуйте, rg45.

W>Блин, когда 101% времени сидишь за прикладным кодом, голова вообще отказывается работать в направлении шаблонов
W>Пишу в рамках С++11. Хочу сделать функцию, которая принимает произвольный вызываемый объект (без учета возвратного значения), и возвращает функтор с подобной сигнатурой, но этот функтор не вызывает исходный объект, а лишь ставит его в очередь сообщений, прибиндивая к нему те параметры, с которыми был вызван этот функтор. По-моему, это что-то похожее на async.
W>Что-то такое:
W>
W>template<typename T>
W>auto defer(const T& fnc) -> typename std::function<typename stdext::call_traits<T>::signature> // stdext::call_traits<T> - это твои трейты, только в нижнем регистре :)
W>{
W>  std::function<typename stdext::call_traits<T>::signature> result = [fnc](???) // Вот что записать тут?
W>  {
W>    add_message_in_queue(???); // И тут
W>  };

W>  return result;
W>}
W>


Ну, если я правильно понял идею, то так:

template<typename T>
auto defer(const T& fnc) -> typename std::function<typename stdext::call_traits<T>::signature> // stdext::call_traits<T> - это твои трейты, только в нижнем регистре :)
{
  std::function<typename stdext::call_traits<T>::signature> result = [fnc](auto&&...args)  // Вот что записать тут?
  {
    add_message_in_queue(fnc(std::forward<decltype(args)>(args)...)); // И тут
  };

  return result;
}


Хотя, из твоего описания, вроде бы, следует, что тут нужна еще одна обертка из std::function. Даже если и так, то там будет все по образу и подобию, как я показал.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 18.08.2020 9:33 rg45 . Предыдущая версия . Еще …
Отредактировано 18.08.2020 9:30 rg45 . Предыдущая версия .
Re[18]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 18.08.20 09:37
Оценка:
Здравствуйте, ollv, Вы писали:

O> так typedef TYPE_OF_3_PARAMETER(func(int(), int(), int(), int())) third_parameter_type; ?\


Ну например, только троечка должна быть параметром, а не частью имени, конечно же.
Re[3]: Получить сигнатуру из ламбды
От: night beast СССР  
Дата: 18.08.20 09:37
Оценка: 5 (2)
Здравствуйте, Went, Вы писали:

W>Блин, когда 101% времени сидишь за прикладным кодом, голова вообще отказывается работать в направлении шаблонов

W>Пишу в рамках С++11. Хочу сделать функцию, которая принимает произвольный вызываемый объект (без учета возвратного значения), и возвращает функтор с подобной сигнатурой, но этот функтор не вызывает исходный объект, а лишь ставит его в очередь сообщений, прибиндивая к нему те параметры, с которыми был вызван этот функтор. По-моему, это что-то похожее на async.

в рамках 11 проблемно.
шаблонные лямбды (вариант rg45) в 14 появились
как вариант возвращать ручную реализацию
template<typename Sig>
struct FunctionProxy
{
   typedef std::function<void()> fn_type;

   template<typename... Args>
   fn_type operator()(Args&&... args)
   {
      std::tuple<???> t(args); // тип из сигнатуры вытащить
      return [fn, t]() { std::apply(fn, t); };
   }

   std::function<Sig> fn;
}.
Re[4]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 18.08.20 09:39
Оценка:
Здравствуйте, night beast, Вы писали:

NB>в рамках 11 проблемно.

NB>шаблонные лямбды (вариант rg45) в 14 появились

Ах, точно! Забывать начинаю хронологию. Так а что ж там за компилятор тогда? 2013-я студия что ли?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[5]: Получить сигнатуру из ламбды
От: Went  
Дата: 18.08.20 09:49
Оценка:
Здравствуйте, rg45, Вы писали:
R>Ах, точно! Забывать начинаю хронологию. Так а что ж там за компилятор тогда? 2013-я студия что ли?
Она, родимая
Re[6]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 18.08.20 09:50
Оценка:
Здравствуйте, Went, Вы писали:

R>>Ах, точно! Забывать начинаю хронологию. Так а что ж там за компилятор тогда? 2013-я студия что ли?

W>Она, родимая

А что препятствует переходу на что-то более свеженькое?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[7]: Получить сигнатуру из ламбды
От: night beast СССР  
Дата: 18.08.20 10:01
Оценка: +1
Здравствуйте, rg45, Вы писали:

W>>Она, родимая


R>А что препятствует переходу на что-то более свеженькое?


предполагаю, что игроделы неохотно обновляются.
некоторые либы идут в бинарниках, для конкретной студии...
Re[19]: Получить сигнатуру из ламбды
От: ollv СССР https://youtu.be/DQDoYs6wHoo
Дата: 18.08.20 10:01
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, ollv, Вы писали:


O>> так typedef TYPE_OF_3_PARAMETER(func(int(), int(), int(), int())) third_parameter_type; ?\


TB>Ну например, только троечка должна быть параметром, а не частью имени, конечно же.

Отлично. Напиши, как ты это видишь?
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Re[20]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 18.08.20 10:13
Оценка:
Здравствуйте, ollv, Вы писали:

O>Здравствуйте, T4r4sB, Вы писали:


TB>>Здравствуйте, ollv, Вы писали:


O>>> так typedef TYPE_OF_3_PARAMETER(func(int(), int(), int(), int())) third_parameter_type; ?\


TB>>Ну например, только троечка должна быть параметром, а не частью имени, конечно же.

O>Отлично. Напиши, как ты это видишь?
typedef TYPE_OF_PARAMETER(func(int(), int(), int(), int()), 3) third_parameter_type;
Re[7]: Получить сигнатуру из ламбды
От: Went  
Дата: 18.08.20 10:34
Оценка:
Здравствуйте, rg45, Вы писали:
R>А что препятствует переходу на что-то более свеженькое?
Да, коней на переправе не меняют. С новым проектом будет и новая студия. Не хочется тратить время на адаптацию перед релизом.
Re[21]: Получить сигнатуру из ламбды
От: ollv СССР https://youtu.be/DQDoYs6wHoo
Дата: 18.08.20 10:36
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, ollv, Вы писали:


O>>Здравствуйте, T4r4sB, Вы писали:


TB>>>Здравствуйте, ollv, Вы писали:


O>>>> так typedef TYPE_OF_3_PARAMETER(func(int(), int(), int(), int())) third_parameter_type; ?\


TB>>>Ну например, только троечка должна быть параметром, а не частью имени, конечно же.

O>>Отлично. Напиши, как ты это видишь?
TB>
TB>typedef TYPE_OF_PARAMETER(func(int(), int(), int(), int()), 3) third_parameter_type;
TB>

погоди, так это плюсовой вариант и есть. Просто за макросом кое что будет написано. Но ты волен скипать это с глаз долой )
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Re[22]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 18.08.20 15:58
Оценка: :)
Здравствуйте, ollv, Вы писали:

O>погоди, так это плюсовой вариант и есть. Просто за макросом кое что будет написано.


Кое-что из 100 строк копипасты.
То есть если мне понадобится чуть иной вариант, то я должен писать свою копипасту.
Ну и без библиотек, хранящих тонны платформозависимых костылей на каждую платформу, на С++ по сути уже писать нельзя.
Re[4]: Получить сигнатуру из ламбды
От: Went  
Дата: 19.08.20 07:19
Оценка: +1 :)
Здравствуйте, night beast.
Жаль, std::apply только с С++17 появляется Ну, у меня есть велосипедный tuple_call.
Re[5]: Получить сигнатуру из ламбды
От: night beast СССР  
Дата: 19.08.20 07:33
Оценка:
Здравствуйте, Went, Вы писали:

W>Жаль, std::apply только с С++17 появляется Ну, у меня есть велосипедный tuple_call.


ага. такая же фигня.
сделал у себя директорию std и добавляю в нее реализацию функций из стд, которые отсутствуют в текущей используемой версии

там кстати можно попробовать не тупл, а [args...] захватывать.
не знаю правда, сработает ли в 11 стандарте.
Re[23]: Получить сигнатуру из ламбды
От: ollv СССР https://youtu.be/DQDoYs6wHoo
Дата: 19.08.20 09:15
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, ollv, Вы писали:


O>>погоди, так это плюсовой вариант и есть. Просто за макросом кое что будет написано.


TB>Кое-что из 100 строк копипасты.

Так необязательно смотреть этот код. А кейсы и их количество, ну извини пока экспоненциального роста кейсов не наблюдается никаких проблем я не вижу. Более того половина кода такого — генерится.
TB>То есть если мне понадобится чуть иной вариант, то я должен писать свою копипасту.
В нормальной библиотеке оч тяжело найти кейс который не покрыт. Если это самописная — можно подойти к тому кто саппортит этот код.
TB>Ну и без библиотек, хранящих тонны платформозависимых костылей на каждую платформу, на С++ по сути уже писать нельзя.
)) ха — смешно. А на чем можно ?
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Re[24]: Получить сигнатуру из ламбды
От: T4r4sB Россия  
Дата: 19.08.20 10:04
Оценка:
Здравствуйте, ollv, Вы писали:

O>Более того половина кода такого — генерится.


В С++ настолько развитое метапрограммирование, что приходится брать внешние генераторы.
Расстрелять комитет нахрен.
Re[3]: Получить сигнатуру из ламбды
От: Went  
Дата: 19.08.20 13:24
Оценка:
Здравствуйте. Короче, получилось что-то такое:

using namespace md;

namespace md {

void add_to_queue(const std::function<void()>& fnc)
{
  fnc(); // Для проверки просто вызываем
}

template<typename Sig>
struct defer_proxy
{
  template<typename... Args>
  void operator()(Args&&... args)
  {
    // Чтобы протащить в лямбду...
    stdext::call_traits<Sig>::parameter_types args_tuple(std::forward<Args>(args)...);  // Пакуем аргументы в туплу
    auto fn_ = std::move(fn);                                                           // И функцию в локал 

    add_to_queue([fn_, args_tuple](){stdext::call_elements(fn_, args_tuple);}); // call_elements = std::apply
  } 

  std::function<Sig> fn;
};


template<typename T>
auto defer(const T& fn) -> typename std::function<typename stdext::call_traits<T>::signature>
{
  return defer_proxy<typename stdext::call_traits<T>::signature>{fn};
}

} // md

int main(int argc, char * argv[])
{
  auto x = [](int i, float f)
  {
    std::cout << i << " " << f << std::endl;
  };
  defer(x)(1, 1.0f);

  std::function<void(int, float)> y = x;
  defer(y)(2, 2.0f);

  return 0;
}


Запустить "как есть" его не получится (call_traits и call_elements), но, может, будут какие-то замечания просто при взгляде на него?
Отредактировано 19.08.2020 13:31 Went (Разметка) . Предыдущая версия .
Re[4]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 19.08.20 13:36
Оценка:
Здравствуйте, Went, Вы писали:

W>Запустить "как есть" его не получится (call_traits и call_elements), но, может, будут какие-то замечания просто при взгляде на него?


Я бы предложил сделать такое упрощение
    add_to_queue([fn_ = std::move(fn), args_tuple](){stdext::call_elements(fn_, args_tuple);});} // call_elements = std::apply

А то выходит, что ты сначала делаешь move и тут же копирование.

И второе, несколько смущает такая одноразовость объектов defer_proxy. Повторное использование чревато UB. Я бы подумал, как можно обезопасить код.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 19.08.2020 13:38 rg45 . Предыдущая версия .
Re[4]: Получить сигнатуру из ламбды
От: night beast СССР  
Дата: 19.08.20 13:37
Оценка:
Здравствуйте, Went, Вы писали:

W>Здравствуйте. Короче, получилось что-то такое:


W>Запустить "как есть" его не получится (call_traits и call_elements), но, может, будут какие-то замечания просто при взгляде на него?


вроде бы [fn, args...]() { fn_(std::move(args)...); }
должно сработать.
Отредактировано 19.08.2020 13:37 night beast . Предыдущая версия .
Re[5]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 19.08.20 13:46
Оценка:
Здравствуйте, night beast, Вы писали:

NB>вроде бы [fn, args...]() { fn_(std::move(args)...); }

NB>должно сработать.

В результате move можно получить нежелательное преобразование к rvalue и нарваться на несовместимость фактических и формальных параметров.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 19.08.2020 13:48 rg45 . Предыдущая версия .
Re[6]: Получить сигнатуру из ламбды
От: night beast СССР  
Дата: 19.08.20 14:23
Оценка:
Здравствуйте, rg45, Вы писали:

NB>>вроде бы [fn, args...]() { fn_(std::move(args)...); }

NB>>должно сработать.

R>В результате move можно получить нежелательное преобразование к rvalue и нарваться на несовместимость фактических и формальных параметров.


в какой ситуации? если параметр не const ссылка? тогда и захват значения смысла иметь не будет.
Re[4]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 19.08.20 14:58
Оценка:
Здравствуйте, Went, Вы писали:

W>Запустить "как есть" его не получится (call_traits и call_elements), но, может, будут какие-то замечания просто при взгляде на него?


Виталик, а можешь объяснить, чем не устраивает "лобовой" вариант? Повторный вызов defer_proxy ведь у тебя все равно невозможен (UB), так какой смысл отделять функтор от параметров?

http://coliru.stacked-crooked.com/a/be68f70b50a6c00b

#include <iostream>
#include <functional>

namespace md {

void add_to_queue(const std::function<void()>& fnc)
{
  fnc(); // Для проверки просто вызываем
}

template<typename F, typename...Args>
void defer(F&& fn, Args&&...args)
{
  return add_to_queue([=](){fn(args...);});
}

} // md

int main(int argc, char * argv[])
{
  auto x = [](int i, float f)
  {
    std::cout << i << " " << f << std::endl;
  };
  md::defer(x, 1, 1.0f);

  std::function<void(int, float)> y = x;
  md::defer(y, 2, 2.0f);
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 19.08.20 15:42
Оценка: 4 (1)
Здравствуйте, Went, Вы писали:

W>Запустить "как есть" его не получится (call_traits и call_elements), но, может, будут какие-то замечания просто при взгляде на него?


Вот тебе еще один вариант. В точности в твоей постановке, но гораздо проще в реализации, без туплов и всяких мета-чудес:

http://coliru.stacked-crooked.com/a/3f41b4c768c465c2

#include <iostream>
#include <functional>

namespace md {

void add_to_queue(const std::function<void()>& fnc)
{
  fnc(); // Для проверки просто вызываем
}

template<typename F>
struct defer_proxy
{
  template<typename... Args>
  void operator()(Args&&... args) const
  {
    auto&& fn_ = fn;
    add_to_queue([=](){fn_(args...);}); // call_elements = std::apply
  } 
  F fn;
};


template<typename F>
defer_proxy<F> defer(const F& fn)
{
  return {fn};
}

} // md

int main(int argc, char * argv[])
{
  auto x = [](int i, float f)
  {
    std::cout << i << " " << f << std::endl;
  };
  md::defer(x)(1, 1.0f);

  std::function<void(int, float)> y = x;
  md::defer(y)(2, 2.0f);
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 19.08.2020 15:48 rg45 . Предыдущая версия .
Re[5]: Получить сигнатуру из ламбды
От: Went  
Дата: 19.08.20 16:21
Оценка:
Здравствуйте, rg45, Вы писали:
R>Я бы предложил сделать такое упрощение
R>
R>    add_to_queue([fn_ = std::move(fn), args_tuple](){stdext::call_elements(fn_, args_tuple);});} // call_elements = std::apply
R>

R>А то выходит, что ты сначала делаешь move и тут же копирование.
Увы, в С++11 присвоение внутри списков захвата не завезли...

R>И второе, несколько смущает такая одноразовость объектов defer_proxy. Повторное использование чревато UB. Я бы подумал, как можно обезопасить код.

Да, с одноразовостью я погорячился, ее там быть не должно. Придется делать обычное копирование, еще и 2 раза.
Re[5]: Получить сигнатуру из ламбды
От: Went  
Дата: 19.08.20 16:22
Оценка:
Здравствуйте, night beast, Вы писали:
NB>вроде бы [fn, args...]() { fn_(std::move(args)...); }
NB>должно сработать.
Проверю, но не уверен, что в С++11 есть захват паков параметров...
Re[6]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 19.08.20 16:31
Оценка:
Здравствуйте, Went, Вы писали:

W>Да, с одноразовостью я погорячился, ее там быть не должно. Придется делать обычное копирование, еще и 2 раза.


Ты локальный fn_ можешь сделать ссылкой на мембер. Лямбда все равно по значению его возьмет.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 19.08.2020 16:34 rg45 . Предыдущая версия .
Re[5]: Получить сигнатуру из ламбды
От: Went  
Дата: 19.08.20 16:33
Оценка: 1 (1)
Здравствуйте, rg45, Вы писали:
R>Виталик, а можешь объяснить, чем не устраивает "лобовой" вариант? Повторный вызов defer_proxy ведь у тебя все равно невозможен (UB), так какой смысл отделять функтор от параметров?
R>http://coliru.stacked-crooked.com/a/be68f70b50a6c00b
Во-первых, я погорячился, и повторный вызов должен работать корректно
Во-вторых, вызов функции defer не должен добавлять вызов в список сразу, а должен создавать функцию эквивалентной сигнатуры, вызов которой уже "сбиндит" прокси-функцию и положит ее в очередь обработки.
Вот небольшой пример использования (функции и классы из головы):
// Какая-то демо-функция
void log(std::string text)
{
  log() << text;
}

Socket<void(std::string)> n_input;

int main()
{
  // Это код вызовет запись в лог немедленно
  n_input.connect(&log);
  n_input("Instant notification"); // То есть после этой строчки в логе уже надпись "Instant notification"
  n_input.disconnect_all();

  // А этот код покладет запись в лог в очередь, которая обработается "когда-то потом"
  n_input.connect(defer(&log));
  n_input("Defered notification"); // То есть после этой строчки в логе сразу ничего не появится

  process_queue(); // А после этой строчки - в логе появится "Defered notification"
}
Re[5]: Получить сигнатуру из ламбды
От: Went  
Дата: 19.08.20 16:38
Оценка:
Здравствуйте, rg45, Вы писали:
R>Вот тебе еще один вариант. В точности в твоей постановке, но гораздо проще в реализации, без туплов и всяких мета-чудес:
Да, выглядит попроще, на работе проверю. Сбилдит ли такое компилер VS2013.
Re[6]: Получить сигнатуру из ламбды
От: rg45 СССР  
Дата: 19.08.20 16:45
Оценка: +1
Здравствуйте, Went, Вы писали:

W>Да, выглядит попроще, на работе проверю. Сбилдит ли такое компилер VS2013.


Ну а куда он денется, там проще уже некуда. Обрати внимание, в gcc этот пример скомпилирован в режиме c++11.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[7]: Получить сигнатуру из ламбды
От: Went  
Дата: 20.08.20 07:32
Оценка: 1 (1)
Здравствуйте, rg45, Вы писали:
R>Ну а куда он денется, там проще уже некуда. Обрати внимание, в gcc этот пример скомпилирован в режиме c++11.
Да, собралось, спасибо.
Re[25]: метапрограммирование
От: ollv СССР https://youtu.be/DQDoYs6wHoo
Дата: 27.08.20 16:17
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, ollv, Вы писали:


O>>Более того половина кода такого — генерится.


TB>В С++ настолько развитое метапрограммирование, что приходится брать внешние генераторы.

Знаешь, есть задачи которые никак не могут быть решены с помощью допустим того-же C#. С прогибанием уже существующего кода, который писали лет 20-30. А без этого забавно наблюдать как проект уходит в состояние экспоненциального взрыва. А еще забавнее попадать на проект, когда он уже в таком состоянии, когда добавление одного кейса (в правильном месте) требует наличие как минимум опытного синьера для тривиальной таски. Так вот, в плюсах в большинстве случаев, вывести проект из этого состояния, или двинуть в разработку параллельную архитектуру, с новой концепцией еще возможно, в то время как без метапрограмминга такие проекты, в большинстве своем, можно смело закапывать

TB>Расстрелять комитет нахрен.

Возможно комитет затянул с 11 стандартом, но в таком случае надо справедливо добавить, что Страуструпу надо поставить памятник. Может быть boost::MPL выглядел бы совсем по другому, а может и не было бы его.

П/С Вообще, я ожидал большего в таком контексте. Предъявлять претензии к языку за наличие метапрограмминга, мне кажется, не аргумент. На С++ можно строить архитектуру, во всяком случае некоторые ее части, вообще исключая шаблоны и метапрограммирование, в таком случае я наблюдал быстрый переход шарповиков из С# -> C++. Я ожидал, что разговор пойдет про ATS и прочие языки в парадигме доказательных алгоритмов. Там да дискуссия была бы интересна. А так вопросы из разряда — баба яга против, не совсем интересно. Дело в том, что есть много разных "фе" по каждому языку, но на основании этого требовать расстрела комитетов имхо некомильфо
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Re[26]: метапрограммирование
От: T4r4sB Россия  
Дата: 27.08.20 18:28
Оценка:
Здравствуйте, ollv, Вы писали:

O>П/С Вообще, я ожидал большего в таком контексте. Предъявлять претензии к языку за наличие метапрограмминга, мне кажется, не аргумент.


Я предъявляю языку за необоснованные претензии на якобы метапрограмминг.

O>Я ожидал, что разговор пойдет про ATS и прочие языки в парадигме доказательных алгоритмов.


Если тебе интересно — моё мнение, что быстрее написать и отладить на тех же прости господи крестах, чем доказать в ATS что твой код ок. Особенно если код быстро меняется.
Re[27]: метапрограммирование
От: ollv СССР https://youtu.be/DQDoYs6wHoo
Дата: 27.08.20 19:06
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, ollv, Вы писали:


O>>П/С Вообще, я ожидал большего в таком контексте. Предъявлять претензии к языку за наличие метапрограмминга, мне кажется, не аргумент.


TB>Я предъявляю языку за необоснованные претензии на якобы метапрограмминг.

А почему якобы ?

O>>Я ожидал, что разговор пойдет про ATS и прочие языки в парадигме доказательных алгоритмов.


TB>Если тебе интересно — моё мнение, что быстрее написать и отладить на тех же прости господи крестах, чем доказать в ATS что твой код ок. Особенно если код быстро меняется.

а я вот думаю, что критические к сафети куски кода должны писаться именно на таких языках. Т/к неверная работа, логические ошибки и конфликты дороже выходят.
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Re[28]: метапрограммирование
От: T4r4sB Россия  
Дата: 27.08.20 21:44
Оценка:
Здравствуйте, ollv, Вы писали:

O> А почему якобы ?


Потому что если нужна внешняя кодогенерация, то у языка не мет, а говно собачье.
Re[29]: метапрограммирование
От: ollv СССР https://youtu.be/DQDoYs6wHoo
Дата: 09.09.20 13:35
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, ollv, Вы писали:


O>> А почему якобы ?


TB>Потому что если нужна внешняя кодогенерация, то у языка не мет, а говно собачье.

При всем том, что я не совсем понимаю в деталях, что ты подразумеваешь под фразой "внешняя кодогенерация"
но я не согласен )))
Дело в том, что таки надо разделать язык, и технологические построения на нем. (C# — Net)
C++ COM DCOM bus / web для технологий может что угодно генериться. Ну и как бы надо давать точную задачу которую нельзя сделать с твоей точки зрения средствами С++. А я могу вот тебе сказать точно задачи с которыми не справятся С# и джава

разбор AST в llvm будет внешней кодогенерацией ?
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.