Constantine
Возможность преобразования возвращаемого типа - явная ошибка std::function
Anatoly
ну
Anatoly
std::function<CStringA(CStringA)> a = [](CStringA s) { return "" + s; }; auto s = a("34");
Anatoly
возвращает CStringA
Constantine
std::function<CStringA(CStringA)> a = [](CStringA s) { return "" + s; }; auto s = a("34");
в тернарке s == "" ? "" : s отрабатывает type deduction и говорит вернуть const char*
Constantine
в тернарке s != "" ? s : "" вернет CStringA
Олександр
Возможность преобразования возвращаемого типа - явная ошибка std::function
Нет, это твоя ошибка. Преобразование типов это то, что ты сам хочешь получить :)
Constantine
Нет, это твоя ошибка. Преобразование типов это то, что ты сам хочешь получить :)
Я не хочу получать преобразование типа указателя на функцию
Vladislav
Олександр
Я не хочу получать преобразование типа указателя на функцию
Так обьяви std::function нормально, лол. И лямбду тоже.
Anatoly
return s == "" ? CStringA("") : s;
Constantine
Так обьяви std::function нормально, лол. И лямбду тоже.
Лол мы обсуждаем вопрос что я виноват потому что я накосячил, а то что std::function выполнил по сути преобразование типа LPCSTR (*)(CStringA) в CStringA (*)(CStringA) тебя не напрягает?
Constantine
дык, это проблема CStringA
это преобразование почти всегда безопасно
Anatoly
но в данном случае нет
Constantine
в данном случае это ошибка std::function
Олександр
Лол мы обсуждаем вопрос что я виноват потому что я накосячил, а то что std::function выполнил по сути преобразование типа LPCSTR (*)(CStringA) в CStringA (*)(CStringA) тебя не напрягает?
std::function принимает не тип функциональной ссылки, а возвращаемый тип и список типов аргументов. Преобразование происходит не самой лямбды, а в operator().
Anatoly
CStringA может быть сконструирован из const char*
Anatoly
напишешь std::function<int(CStringA)>
Anatoly
получишь по рукам
Anatoly
так что это над тобой CStringA поиздевался
Constantine
а по-моему std::function<void()> это должно быть хотя быть что-то, что могло быть скомпилировано, возвращая void
Олександр
Т.е. у тебя выходит CStringA operator() { return savedlambda(); };
Constantine
std::function<void()> lambda1 = [&] () { //OK return lambda1; }; std::function<void()> lambda2 = [&] () -> void { //CE return lambda2; };
Олександр
Ну и? Здесь тоже все норм. В первом случае при возвращении значение кастится в void, во втором случае ты пытаешься вернуть значение из функции с void.
Constantine
Ну то есть вы не считаете, что такое поведение является by design ошибкой для std::function? :)
Berkus
чот я не понял с какого хуя вам там преобразование то вдруг впилось? тернарка возвращает ОДИН тип и это CStringA
Anatoly
тернарка возвращает const char*
Anatoly
во всяком случае в таком виде return s == "" ? "" : s;
Constantine
чот я не понял с какого хуя вам там преобразование то вдруг впилось? тернарка возвращает ОДИН тип и это CStringA
тернарка задедуктилась по типу первого аргумента, а второй преобразовала
Constantine
std::function<CStringA(CStringA)> echo = [](CStringA s) -> CStringA { //было бы верно return s == "" ? "" : s; }
Anatoly
тебя подвел их конструктор CStringT(_In_opt_z_ const XCHAR* pszSrc) :
Constantine
ну смотрите, я жду от std::function поведения, которое соответствует поведению указателей на функции
Constantine
по сути std::function построила новую функцию, добавив мне оператор преобразования в конец
Anatoly
просто вывод типа в условиях неопределенности сопровождается сюрпризами из-за вольностей позволяемых тем же CStringA
Anatoly
c std::string у тебя такого не будет
Constantine
все в порядке, пока речь не идет о выражениях, допускающих преобразование типа и при этом выходящих за scope
Constantine
как ни странно, но до этого момента этими вольностями CStringA расстрелов ноги не было
Constantine
там очень сложно ее построить auto p = (s == "" ? "" : s); //вывело LPCTSTR из s, которая все еще верна в scope
Constantine
Ну вообще да, atl не нужен. Но и std::function ведёт себя по-свински
Даже не используя слово из 6 букв, достаточно сложно придумать альтернативу под вин :)
Anatoly
наоборот, он сделал все что мог
Constantine
короче я это все запретил и у меня никаких проблем :)
Anatoly
ладно, пусть функция возвращает CStringA, ты мне вернул const char*, ладно, ведь CStringA может же из него сконструировать
Vladislav
наоборот, он сделал все что мог
Добавил пару имплисит кастов там, где его не просили?
Constantine
я в принципе не понимаю, зачем std::function допускает преобразование возвращаемых типов
🦥Alex Fails
Затем
Anatoly
Добавил пару имплисит кастов там, где его не просили?
гы-гы, если бы он этого не сделал была бы армия возмуженных
Anatoly
думаю, в комитете были дебаты на этот счет
🦥Alex Fails
Затем
Я заебался вчера об этом говорить, зачем. Даже Андрея потревожил
Constantine
всей армии возмуженных можно было сделать std::allow_implicit_cast
Anatoly
сделать тупую куклу или сделать интеллектуальный аппарат std::function
Vladislav
гы-гы, если бы он этого не сделал была бы армия возмуженных
Если слушать армию возмущенных, эдак в пхп скатить язык можно
Anatoly
ну, так или иначе, интеллект перевесил
Anatoly
ага, и лаконичности конец
Anatoly
в конечном итоге, за это идет сейчас борьба
Constantine
> интеллектуальный аппарат что-то я не помню, какие там маркировки у std::shared_ptr<T>::shared_ptr(T*)
Constantine
это создает 0 лаконичности
Anatoly
make_shared
Constantine
если принимается void() и туда передается int() кажется здесь какой-то костыль
Vladislav
ага, и лаконичности конец
Из-за такой же любви к лаконичности можно 0 скастить к любому указателю, разве это хорошо?
🦥Alex Fails
В общем, можно пропознуть explicit templatea
Vladislav
Это же цэ(
Ну вот решение о касте возврата в std::function - оно в стиле цэ
Vladislav
Жертвуем строгостью в пользу сомнительного упрощения частного случая (не факт что часто нужного)
Berkus
тернарка возвращает const char*
окей, но ретурн валью это CStringA так что оно кастится обратно
Anatoly
ретурн валуе у std::function но не лябмды
Constantine
окей, но ретурн валью это CStringA так что оно кастится обратно
только второй каст происходит вне scope функции и s уже померло
Anatoly
поэтому const char* уже указывает на мусор
Anatoly
короче CStringA зло
Berkus
короче CStringA зло
как и примерно весь MFC и ATL
Constantine
ага
Berkus
но этот пример не характерен для ATL
Berkus
любая либа с такими преобразованиями будет подвержена
Berkus
зло тут implicit casts :)
Anatoly
ну, это и имелось ввиду