template<class L> Subscribe(L lambda)
{
std::function<сигнатура вызова lambdы> f; // типа void(int, int)
std::function<void(сигнатура параметров lambdы)> f; // типа только "int, int"
}
Subscribe([](int, int){});
возможно както?
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Список аргументов можно добыть через tuple<Args...> to parameter pack mapping. Здесь недостаёт recognition rules для function volatile qualifier только.
Здравствуйте, 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 г.
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, Barbar1an, Вы писали:
_NN>На всякий случай серия статей насколько это непросто разобрать указатель на функцию:
Годы шли, а крестоговнари так и не добавили в язык рефлексию.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
_NN>>На всякий случай серия статей насколько это непросто разобрать указатель на функцию:
TB>Годы шли, а крестоговнари так и не добавили в язык рефлексию.
Годы шли, стандарты плюсов расширялись и дополнялись, расширялись и дополнялись, а говнокодеры так и не удосужились изучить что-то новое для себя. Особо говнистые живут в 0x03ем году, и только выступать и умеют
Во-первых праметер-пак(class ...L) не нужен. Что ожидает в качестве темплейт-параметра CActiveDelegate? Если сигнатуру функции (как fastdelegate), то попробуй:
и все равно не проходит
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 г.
Здравствуйте, Barbar1an, Вы писали:
B>Здравствуйте, YuriV, Вы писали:
YV>>Во-первых праметер-пак(class ...L) не нужен.
B>точно, это я перестарался
YV>>Что ожидает в качестве темплейт-параметра CActiveDelegate?
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 наверное.
Здравствуйте, 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 г.
Здравствуйте, 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 всё ок
Ну запости лог без
Здравствуйте, 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 г.
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Здравствуйте, Marty, Вы писали:
M>Годы шли, стандарты плюсов расширялись и дополнялись, расширялись и дополнялись, а говнокодеры так и не удосужились изучить что-то новое для себя. Особо говнистые живут в 0x03ем году, и только выступать и умеют
Что, добавили новую категорию объектов, из-за чего в класс вектора пришлось добавить ещё 5 видов конструкторов, и ещё 3 случая в метод реаллокации?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
M>>Годы шли, стандарты плюсов расширялись и дополнялись, расширялись и дополнялись, а говнокодеры так и не удосужились изучить что-то новое для себя. Особо говнистые живут в 0x03ем году, и только выступать и умеют
TB>Что, добавили новую категорию объектов, из-за чего в класс вектора пришлось добавить ещё 5 видов конструкторов, и ещё 3 случая в метод реаллокации?
Здравствуйте, 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' и всех их комбинаций (это если требуется поддержка пользовательских классов функциональных объектов).
Здравствуйте, T4r4sB, Вы писали:
TB>Что, добавили новую категорию объектов, из-за чего в класс вектора пришлось добавить ещё 5 видов конструкторов, и ещё 3 случая в метод реаллокации?
Слушай, надоел ты уже своим нытьем. Иди в эвакуаторщики, если для тебя все так сложно.
TB>Даже-не-джуниор, который пишет в стиле "мамкин хацкер", и не понимает, почему другим это не нравится, будет меня учить?
Тебе до моего стиля, расти и расти. Только учить тебя у меня никакого желания нет, ибо бесполезно. Просто нытье твое невежественное достало. В каждой теме одно и то же.
Здравствуйте, T4r4sB, Вы писали:
TB>Тебе что, 45 лет?
Это ж пипец, и я еще о чем-то дискутирую с этим человеком
А я что, профиль на РСДН только в этом году завел? Или, может быть, ники каждый год меняю? Гигант мысли ты наш.
TB>Ну тогда респект за то, что в таком возрасте ты остался юн душою!
А, то есть, 45 лет — для тебя это "ТАКОЙ ВОЗРАСТ"? Я, вообще-то думал, что это тебе 45, ошибся походу
Здравствуйте, rg45.
А насколько можно быть увереным, что у лямбды не будет перегруженного оператора скобки? За исключением обобщенных лямбд, возможны отказы в подобной реализации трейтов?
Здравствуйте, Went, Вы писали:
W>А насколько можно быть увереным, что у лямбды не будет перегруженного оператора скобки? За исключением обобщенных лямбд, возможны отказы в подобной реализации трейтов?
Признаться, никаких гарантий я найти не смог. Ни по поводу отсутствия дополнительных перегрузок, ни по поводу наличия единственного необходимого оператора. Так что здесь вся надежда на здравый смысл и результаты эксперимента на разных компиляторах. Ну в самом деле, что это может быть, если не operator() и каким образом может оказаться несколько перегрузок?
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, T4r4sB, Вы писали:
TB>>Я вырос из "сложна эта крута", а ты нет.
R>Это нормально. Мне в твоем возрасте тоже казалось, что я вырос.
Ты даже какашками кидаешься так, будто 2006 это не твоя дата регистрации, а твоя дата рождения.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
TB>Стиль "я крутой, потому что умею писать сложно"? Это уровень младших курсов, гуляй.
Точно, я вообще подозреваю что rg45 — виндузятник. И такие приходят на форум программистов.
Запомните: C++ — это С++03, а именно С с классами. Остальной треш придумали графоманы.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, rg45, Вы писали:
R>>Когда я был на младших курсах, ты пешком под стол ходил, мой юный друг.
TB>Тебе что, 45 лет? Ну тогда респект за то, что в таком возрасте ты остался юн душою!
Дам совет. На фото rg45 одет в обычное ХБ. По всей видимости это повседневка, такую в мою бытность уже носили только для черновых работ, т/е служил он точно раньше 89-го года.
И да — меня тоже раздражает, когда кто-то мыслит так как ты. Если написано сложно, то так писать нельзя. Сложно, иногда — необходимость, и сршенно все равно, может понять это кто-то, или нет. (Вон квантовую механику никто не понимает, главный лозунг — считай и не думай (не помню, кто там кому об этом говорил))
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Здравствуйте, lpd, Вы писали:
lpd>Здравствуйте, T4r4sB, Вы писали:
TB>>Стиль "я крутой, потому что умею писать сложно"? Это уровень младших курсов, гуляй.
lpd>Точно, я вообще подозреваю что rg45 — виндузятник. И такие приходят на форум программистов. lpd>Запомните: C++ — это С++03, а именно С с классами. Остальной треш придумали графоманы.
Ого )) сильно заявление. Каким образом стандарт С++ привязан к платформе ? Виндузятник/линуксовик это вообще важно в контексте С++ ..
Думаешь от количества платформ, под которые ты разрабатываешь меняется уровень осознания когда и возможностей ? Вот сейчас имею четыре разные платформы разработки мак / винда / айос / линукс и прочие фрибзди, а задачи и проект все равно — г. А вот под винду, иногда, приходилось уух знатно покодить (архитектурно с компайлтайм рефлекшинами мега хаками) мало кто понимал тот код. Всего двое, но только эти двое и могли писать в этом сегменте, своего рода защита от,... тех кому может не понравиться такой код.
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Здравствуйте, lpd, Вы писали:
lpd>Точно, я вообще подозреваю что rg45 — виндузятник.
Оп-па! Козыри пошли
Действительно, что может знать о C++ какой-то виндузятник.
Прямо по Жванецкому
lpd>И такие приходят на форум программистов.
Ну я, по крайней мере, попытался дать вариант решения. А вот с какой целью ты приходишь? По-видимому, обсуждать мою личность — это максимум твоих возможностей.
lpd>Запомните: C++ — это С++03, а именно С с классами. Остальной треш придумали графоманы.
Ты к кому обращаешься сейчас? Кто должен запомнить, и почему твое невежество того стоит?
Здравствуйте, T4r4sB, Вы писали: TB>Ты даже какашками кидаешься так, будто 2006 это не твоя дата регистрации, а твоя дата рождения.
Ты самостоятельно нашел несоответствие между реальностью и своими ощущениями? Поздравляю. Ты на пути к выздоровлению.
У меня только одна маленькая просьба к тебе: постарайся ныть поменьше, ладно?
Скрытый текст
Ну в самом деле, человек задает конкретный вопрос, можешь помочь — замечательно. Не можешь — ну просто почитай, что пишут другие. Пройди мимо, наконец. А кому интересны вот эти стоны — как все сложно и какие все плохие
Здравствуйте, 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()".
O>И да — меня тоже раздражает, когда кто-то мыслит так как ты. Если написано сложно, то так писать нельзя. Сложно, иногда — необходимость, и сршенно все равно, может понять это кто-то, или нет.
Иногда сложность вызвана кулхацкерскими амбициями, иногда — идиотским дизайном языка. В этих случаях необходимости нет.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
_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()() ? В это хочется верить, конечно, и эксперименты это подтверждают, но... остается некоторая неудовлетворенность.
Здравствуйте, 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,
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, ollv, Вы писали:
O>>И да — меня тоже раздражает, когда кто-то мыслит так как ты. Если написано сложно, то так писать нельзя. Сложно, иногда — необходимость, и сршенно все равно, может понять это кто-то, или нет.
TB>Иногда сложность вызвана кулхацкерскими амбициями, иногда — идиотским дизайном языка.
Давай выражаться конкретно, что тебе конкретно не нравится в том, что трейтсы в С++ с шаблонами и классами выглядят именно так.
Что ты предложил бы в замен (да в рамках реально работающего компилятора С++) ? НЕ нравится С++ в целом — никто не заставляет. НЕ нравятся шаблоны — предложи как лучше распарсить сигнатуру в компайлтайм. Вот это против всего плохого за все хорошее — не тот топик.
TB>В этих случаях необходимости нет.
Как это нет ? Нет необходимости парсить сигнатуру? Молодец
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Здравствуйте, ollv, Вы писали:
O> Давай выражаться конкретно, что тебе конкретно не нравится в том, что трейтсы в С++ с шаблонами и классами выглядят именно так. O>Что ты предложил бы в замен (да в рамках реально работающего компилятора С++) ?
Я бы предложил расстрелять комитет для начала. И добавить в язык ключевые слова, которые бы прямо возвращали параметры сигнатуры.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
TB>Я бы предложил расстрелять комитет для начала. И добавить в язык ключевые слова, которые бы прямо возвращали параметры сигнатуры.
Здравствуйте, 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. Я болен ПГМ.
Ключевое слово, параметр — указатель на функцию или функциональный тип, или тип с оператором (), возвращающее тип.
Я не знаю, что такое GET_TYPE_BASED_SIGN_MACRO
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, 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. Я болен ПГМ.
Здравствуйте, 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.
}
Здравствуйте, 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. Я болен ПГМ.
Здравствуйте, 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. Даже если и так, то там будет все по образу и подобию, как я показал.
Здравствуйте, Went, Вы писали:
W>Блин, когда 101% времени сидишь за прикладным кодом, голова вообще отказывается работать в направлении шаблонов W>Пишу в рамках С++11. Хочу сделать функцию, которая принимает произвольный вызываемый объект (без учета возвратного значения), и возвращает функтор с подобной сигнатурой, но этот функтор не вызывает исходный объект, а лишь ставит его в очередь сообщений, прибиндивая к нему те параметры, с которыми был вызван этот функтор. По-моему, это что-то похожее на async.
в рамках 11 проблемно.
шаблонные лямбды (вариант rg45) в 14 появились
как вариант возвращать ручную реализацию
Здравствуйте, 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. Я болен ПГМ.
Здравствуйте, ollv, Вы писали:
O>Здравствуйте, T4r4sB, Вы писали:
TB>>Здравствуйте, ollv, Вы писали:
O>>> так typedef TYPE_OF_3_PARAMETER(func(int(), int(), int(), int())) third_parameter_type; ?\
TB>>Ну например, только троечка должна быть параметром, а не частью имени, конечно же. O>Отлично. Напиши, как ты это видишь?
Здравствуйте, rg45, Вы писали: R>А что препятствует переходу на что-то более свеженькое?
Да, коней на переправе не меняют. С новым проектом будет и новая студия. Не хочется тратить время на адаптацию перед релизом.
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, ollv, Вы писали:
O>>Здравствуйте, T4r4sB, Вы писали:
TB>>>Здравствуйте, ollv, Вы писали:
O>>>> так typedef TYPE_OF_3_PARAMETER(func(int(), int(), int(), int())) third_parameter_type; ?\
TB>>>Ну например, только троечка должна быть параметром, а не частью имени, конечно же. O>>Отлично. Напиши, как ты это видишь? TB>
Здравствуйте, ollv, Вы писали:
O>погоди, так это плюсовой вариант и есть. Просто за макросом кое что будет написано.
Кое-что из 100 строк копипасты.
То есть если мне понадобится чуть иной вариант, то я должен писать свою копипасту.
Ну и без библиотек, хранящих тонны платформозависимых костылей на каждую платформу, на С++ по сути уже писать нельзя.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, ollv, Вы писали:
O>>погоди, так это плюсовой вариант и есть. Просто за макросом кое что будет написано.
TB>Кое-что из 100 строк копипасты.
Так необязательно смотреть этот код. А кейсы и их количество, ну извини пока экспоненциального роста кейсов не наблюдается никаких проблем я не вижу. Более того половина кода такого — генерится. TB>То есть если мне понадобится чуть иной вариант, то я должен писать свою копипасту.
В нормальной библиотеке оч тяжело найти кейс который не покрыт. Если это самописная — можно подойти к тому кто саппортит этот код. TB>Ну и без библиотек, хранящих тонны платформозависимых костылей на каждую платформу, на С++ по сути уже писать нельзя.
)) ха — смешно. А на чем можно ?
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Здравствуйте, Went, Вы писали:
W>Запустить "как есть" его не получится (call_traits и call_elements), но, может, будут какие-то замечания просто при взгляде на него?
Здравствуйте, Went, Вы писали:
W>Здравствуйте. Короче, получилось что-то такое:
W>Запустить "как есть" его не получится (call_traits и call_elements), но, может, будут какие-то замечания просто при взгляде на него?
вроде бы [fn, args...]() { fn_(std::move(args)...); }
должно сработать.
Здравствуйте, rg45, Вы писали:
NB>>вроде бы [fn, args...]() { fn_(std::move(args)...); } NB>>должно сработать.
R>В результате move можно получить нежелательное преобразование к rvalue и нарваться на несовместимость фактических и формальных параметров.
в какой ситуации? если параметр не const ссылка? тогда и захват значения смысла иметь не будет.
Здравствуйте, Went, Вы писали:
W>Запустить "как есть" его не получится (call_traits и call_elements), но, может, будут какие-то замечания просто при взгляде на него?
Виталик, а можешь объяснить, чем не устраивает "лобовой" вариант? Повторный вызов defer_proxy ведь у тебя все равно невозможен (UB), так какой смысл отделять функтор от параметров?
Здравствуйте, Went, Вы писали:
W>Запустить "как есть" его не получится (call_traits и call_elements), но, может, будут какие-то замечания просто при взгляде на него?
Вот тебе еще один вариант. В точности в твоей постановке, но гораздо проще в реализации, без туплов и всяких мета-чудес:
R>А то выходит, что ты сначала делаешь move и тут же копирование.
Увы, в С++11 присвоение внутри списков захвата не завезли...
R>И второе, несколько смущает такая одноразовость объектов defer_proxy. Повторное использование чревато UB. Я бы подумал, как можно обезопасить код.
Да, с одноразовостью я погорячился, ее там быть не должно. Придется делать обычное копирование, еще и 2 раза.
Здравствуйте, night beast, Вы писали: NB>вроде бы [fn, args...]() { fn_(std::move(args)...); } NB>должно сработать.
Проверю, но не уверен, что в С++11 есть захват паков параметров...
Здравствуйте, 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"
}
Здравствуйте, rg45, Вы писали: R>Вот тебе еще один вариант. В точности в твоей постановке, но гораздо проще в реализации, без туплов и всяких мета-чудес:
Да, выглядит попроще, на работе проверю. Сбилдит ли такое компилер VS2013.
Здравствуйте, rg45, Вы писали: R>Ну а куда он денется, там проще уже некуда. Обрати внимание, в gcc этот пример скомпилирован в режиме c++11.
Да, собралось, спасибо.
Здравствуйте, 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. Я болен ПГМ.
Здравствуйте, ollv, Вы писали:
O>П/С Вообще, я ожидал большего в таком контексте. Предъявлять претензии к языку за наличие метапрограмминга, мне кажется, не аргумент.
Я предъявляю языку за необоснованные претензии на якобы метапрограмминг.
O>Я ожидал, что разговор пойдет про ATS и прочие языки в парадигме доказательных алгоритмов.
Если тебе интересно — моё мнение, что быстрее написать и отладить на тех же прости господи крестах, чем доказать в ATS что твой код ок. Особенно если код быстро меняется.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, ollv, Вы писали:
O>>П/С Вообще, я ожидал большего в таком контексте. Предъявлять претензии к языку за наличие метапрограмминга, мне кажется, не аргумент.
TB>Я предъявляю языку за необоснованные претензии на якобы метапрограмминг.
А почему якобы ?
O>>Я ожидал, что разговор пойдет про ATS и прочие языки в парадигме доказательных алгоритмов.
TB>Если тебе интересно — моё мнение, что быстрее написать и отладить на тех же прости господи крестах, чем доказать в ATS что твой код ок. Особенно если код быстро меняется.
а я вот думаю, что критические к сафети куски кода должны писаться именно на таких языках. Т/к неверная работа, логические ошибки и конфликты дороже выходят.
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Здравствуйте, 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. Я болен ПГМ.