LINUX.ORG.RU

Получить тип возвращаемого значения из лямбды

 


3

2

Нюанс в том, что незивестен точный тип лямбды, они приходят из пользовательского кода, следовательно мне неизвестны типы и количество аргументов, которые функтор ожидает, т.е. я не могу использовать invoke_result<>. Нужно заглянуть в класс, схватить любой оператор() и вернуть тип возврата. Получилось такое:


template <typename T>
struct Return_type;
template <typename R, typename... Args>
struct Return_type<R(Args...)> {using type = R;};
template <typename R, typename Q, typename... Args>
struct Return_type<R (Q::*)(Args...)const> {using type = R;};
template <typename R, typename Q, typename... Args>
struct Return_type<R (Q::*)(Args...)> {using type = R;};

struct A{
	struct V {
		double operator()(int t)const {return 5;}
	};
};

int main() {
	auto l = [](double a, int e)mutable{return 2;};
	auto l2 = [](int a){;return 2;};
	Return_type<decltype(&decltype(l)::operator())>::type a;
	Return_type<decltype(&decltype(l2)::operator())>::type a2;
	Return_type<decltype(&A::V::operator())>::type a3;


	auto l3 = [](auto b){;return 2;};
	Return_type<decltype(&decltype(l3)::operator())>::type a4;

	return 0;
}

И в принципе свою задачу я решил, мне этого хватит, но не знаю как (и возможно ли вообще) получить тип от лямбды, внутри которой шаблонный оператор() (тот, что auto l3). Решаема ли задача в случае с l3?

★★
Ответ на: комментарий от Siborgium

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

safocl ★★
()
Ответ на: комментарий от kvpfs

Ладно, раз ты начал исцеляться покажу тебе ещё пару трюков на тему, чтобы ты понял как работает С++.

Основное свойство С++ - это отсутствие некоей гомогенности. Если в обычной скриптухи у нас есть отдельно компилтайм, отдельно какие-то помойные типы, отдельно какие-либо значения.

В C++ же это не так. Всё это свойства в рамках одной системы, но разных классов. И между этими классами возможен переход.

Поэтому ненужно пердолится как в мусорной скриптухе с какими-то invoke_result_t. Я уже показывал примеры.

anonymous
()
Ответ на: комментарий от safocl

Срочно за букварь.

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

Нелепые позорные потуги. Ты даже не знаешь что такое концепты и для чего они нужны. Сообщаю новость, концепты никогда не были нужны для ошибок и прочей подобной херни. И уж никакие правила они не определяют. И уж тем более никакие «строгие» тоже.

Больше читай букварь и меньше неси позорной херни.

anonymous
()

Не понятно только зачем тебе Си++ – этт поделие мертвеца страуса. Не лучше ли писать на Расте и не забивать голову устаревшими технологиями?

anonymous
()
Ответ на: комментарий от safocl

мде… классна быть аноном када несешь такую ахинеальную бредятину…

Ну, себя ты уже показал, как невминяемого собеседника. Начинаешь сливать в споре – переходишь на личности. Аргументации то нету. Оформился ты, ну и что с того? Решил, что все должны последовать за тобой, как табор в небо? Но может тебе просто попробовать набраться смелости не отходить от темы, и подвезти аргументы.

anonymous
()
Ответ на: комментарий от safocl

Это так мило, когда нонейм-клоун будет мне говорить о том, что я анон. Анон здесь ты, балаболка.

Хорошо, давай поиграем в игру. Мы берём постим твою херню бездарную, правда нужно будет указать шильдик, ведь без него никто не признает в тебе ничто. Ты - пыль, которую даже идентифицировать без учётки нельзя.

Далее постим моё сообщение, после спрашиваем «кто знает что-то о мне и о тебе, убогом?», если же тех, кто сообщит о тебе будет меньше, нежели обо мне - ты берёшь свою нелепую жопу и пишешь на ней «я помойный нонейм» на фоне лора с твоей учёткой.

anonymous
()
Ответ на: комментарий от safocl

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

Концепты никаких правил не предоставляют. Концепты влияют на формирование overload set’а. Они ортогональны static_assert, и поэтому не могут быть «куда лучше» или хуже.

Siborgium ★★★★★
()
Ответ на: комментарий от anonymous

вухахаах ну ты же мне грил чо я не понимаю чо такое концепты — ты считаешь чо их следует юзать иначе — однако как раз именно ты не привел изначально никакой аргументации...
следовательно у меня появился обоснованный вывод чо ты просто пишешь ахинеальную бредятину — только ради того что бы хоть чото написать...

как то так...

safocl ★★
()
Ответ на: комментарий от Siborgium

ого — никаких правил???
ясно — а как же тогда что если ты не подставишь тип не удовлетворяющий концепту — выдаст ошибку???
ты же пока не удовлетворишь те требования которые в концепте указаны — не сможешь юзать сущность.

safocl ★★
()
Ответ на: комментарий от safocl

ты просто пишешь ахинеальную бредятину — только ради того что бы хоть чото написать…

Какая ирония.

ясно — а как же тогда что если ты не подставишь тип не удовлетворяющий концепту — выдаст ошибку???

Ошибка никак не связана с несоответствием типа концепту. Она связана исключительно с тем, что overload set оказался пустым. Лапша, вываливаемая компилятором в этом случае – это список кандидатов и причин, по которым они не подошли.

Вот тебе список проблем, которые возникают при использовании концептов не по назначению, а для «предоставления правил»:

  1. Компилятор выдает ошибку, которая уводит пользователя от реальной причины;
  2. Нет человекочитаемого пояснения того, что пошло не так;
  3. Самое важное – overload set может быть не пустым, и тогда, когда ты будешь ожидать ошибку компиляции из-за несоответствия типа концепту, все будет молча компилироваться и работать – но не так, как ты хочешь.
Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)
Ответ на: комментарий от safocl

Очевидно, что он - это не я. И он тебе ничего не говорил. Далее, запомни, табуретка, я не должен ничего предоставлять никакой аргументации. Ты утверждаешь - ты предоставляешь. Я могу отрицать что угодно без какой-либо аргументации - это база, о которой тебе в школе не рассказали. Попытайся ещё раз, вернувшись запарту.

И да, выше я уже говорил как их использовать. Но в любом случае ты отвечаешь не на эти мои тезисы, поэтому как-то раскрывать я их не должен.

anonymous
()

Зачем программисты при написании прикладных программ используют template, …?
Можно подумать, что алгоритмы их прикладных проектов используют какие-то обобщенные алгоритмы.
Скорее всего нет.
Таогда зачем все это высокоумие?
Используйте в проекте обычный struct и не старайтесь его в..ать каким-то необычным и замысловатым способом.
От этого ваш код лучше не станет.

anonymous
()
Ответ на: комментарий от anonymous

Используйте в проекте обычный struct и не старайтесь его в..ать каким-то необычным и замысловатым способом. От этого ваш код лучше не станет.

Такого рода программисты используют метапрограммирование наверное, чтобы показать крутыми?
А на самом деле не понимают для чего оно нужно и когда полезно его использовать.

anonymous
()
Ответ на: комментарий от anonymous

Можно подумать, что алгоритмы их прикладных проектов используют какие-то обобщенные алгоритмы.

Скорее всего нет.

Гоферам так пришлось переписывать половину докера.

Таогда зачем все это высокоумие?

Это не высокоумие.

От этого ваш код лучше не станет.

Станет. Он станет хуже от того, что придется держать в голове все то, что должен делать компилятор.

Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

Гоферам так пришлось переписывать половину докера.

Речь шла о прикладных, а не системных проектах.

anonymous
()
Ответ на: комментарий от anonymous

Речь шла о прикладных, а не системных проектах.

Да и в системных проектах обычно всю эту муть template, … не используют.
Посмотрите исходных код например Firebird, … и … и …

anonymous
()
Ответ на: комментарий от anonymous

Тебе не нравится само обобщенное программирование или то, как оно реализовано в C++? Есть большая разница между этими двумя вещами.

anonymous
()
Ответ на: комментарий от anonymous

Какой все таки замечательный язык программирования C++. Все проще паренной репы.

ахахха, реально собрались любители отведать пареную репу и спорят, как ее лучше есть. подумать, что ее можно вообще не есть, им в голову не приходит, ахахах

anonymous
()

И в принципе свою задачу я решил

в каком месте?

struct B {};
struct A{
	struct V {
		double operator()(int t)const {return 5;}
                double operator()(int, int) const {return 5;}
                double operator() (B) const {return 5;}
	};
};

anonymous
()
Ответ на: комментарий от anonymous

ахахха, реально собрались любители отведать пареную репу и спорят, как ее лучше есть.

Вот вы смеетесь над C+, но посмотрите какой КОД.
Это же картина достойна Айвазовского

template <typename T>
struct Return_type;
template <typename R, typename... Args>
struct Return_type<R(Args...)> {using type = R;};
template <typename R, typename Q, typename... Args>
struct Return_type<R (Q::*)(Args...)const> {using type = R;};
template <typename R, typename Q, typename... Args>
struct Return_type<R (Q::*)(Args...)> {using type = R;};

struct A{
	struct V {
		double operator()(int t)const {return 5;}
	};
};

Все просто и понятно …

anonymous
()
Ответ на: комментарий от anonymous

А будет все еще лучше!

И все повторится сначала!

ООП с пеной у рта и брызгами слюн лет двадцать восхваляли и …
А теперь вот ПРОЗРЕЛИ, что он то и «не очень» да и редко нужен.

Кто знал, что «не очень» НЕ НУЖНО и не использовал его.
Ныне НОВЫЙ БРЕД измышляют.
Ребята, это не метапрограммирование, а

Бред сивой кобылы
anonymous
()
Ответ на: комментарий от kvpfs

Для тех, кто случайно найдет тему и захочет заюзать - тут дефолтная лямбда проинициализирована дефотным конструктором. Наверное ничего страшного, ну лучше так:

struct No_user_handler_tag {};
auto default_branch = [](auto &&) {return No_user_handler_tag{};};
using default_branch_t = decltype(default_branch);

template <typename... Fn>
struct Visitor : Fn..., default_branch_t {
    constexpr Visitor(Fn... fn) : Fn{fn}..., default_branch_t{default_branch} {}
...
};

Также отказался от std::visit в пользу ручного управления

if constexpr( ! is_same_v<invoke_result_t<decltype(vis), T>, No_user_handler_tag>) {
    cout << "invocable with T" << endl;
    //some action
    T p;
    vis(p);
}

что-то вроде контроля за функционалом через тип лямблы без передачи каких-то доп флагов куда-то в родительский конструктор (std::visit не позволяет, т.к не даёт static_assert при невозможности вывести общий тип).

kvpfs ★★
() автор топика
Ответ на: комментарий от anonymous

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

kvpfs ★★
() автор топика
Ответ на: комментарий от kvpfs

Чего там у тебя получилось, табуретка. Тебя спросили про смысл этих нелепых потуг - ты ответить не смог. Мало того, что это не имеет смысла, к тому же заменяется на одно if constexpr(requires {f(x);} {} о чём тебе уже не один раз сказали.

Ладно ты там в язык не можешь - слишком сложно. Но хоть назначение своих потуг попытайся объяснить.

anonymous
()
Ответ на: комментарий от anonymous

Осилил концепты, поздравляю. Наверное ты лишь этим был занят крайние дни.

kvpfs ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.