LINUX.ORG.RU

Функция, принимающая указатель на себе подобную

 


0

2

Как сделать сабж? Через указатели или std::function — не суть.

void foo(int a, ... b);
//на место многоточия надо воткнуть указатель на подобную функцию
//получается так:
void foo(int a, std::function<void(int, std::function<void(int,...WTF)>)>);

И тут я понял, что вложенные определения функции-аргумента никогда не закончатся. Финт с typedef в лоб приводит к тому же самому. Если второй аргумент определить через шаблонный тип, все должно получиться, но мне в конечном счете хочется получить синоним (typedef или еще как) типа такой функции, а там шаблоны вроде как не сработают.

Какие есть еще варианты кроме грязных кастований указателей?

★★★★★

Последнее исправление: beastie (всего исправлений: 3)

Самый простой вариант - сделать функтор(объект с operator()), который бы принимал указатель/ссылку на объект того же типа.

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

Ну вот мысль с функтором и forward declaration мне тоже уже пришла в голову. Но хочется странного^W обойтись без написания классов. По возможности.

staseg ★★★★★
() автор топика

Какие есть еще варианты кроме грязных кастований указателей?

А ещё на темплейтах можно попробовать записать комбинатор. Это весело!

nanoolinux ★★★★
()

Поздравляю тебя, Шарик, ты напоролся на врождённую слабость системы типов в C++.

Попробуй обернуть в класс.

class FUNCA {
  std::function<void(int, FUNCA)> call;
};

Miguel ★★★★★
()

В крестах разве есть рекурсивные типы? Это довольно нетривиально сказывается на проверке типов.

Deleted
()

Какие есть еще варианты кроме грязных кастований указателей?

Сделать свой тип указателя в виде класса с конструктором и оператором (), который будет «прозрачно» отрабатывать при передаче и использовании параметров.

anonymous
()

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

Ты хочешь генерить тип этой функции? Он должен когда-то заканчиваться, или функции должны генериться в зависимости от переданных аргументов?

Это норм?

template <typename S, typename R, typename... Args>
struct get_rec {
	using type = std::function<R(Args..., S)>;
	using next = get_rec<type, R, Args...>;
};

template <typename R, typename... Args>
struct rec_start {
	using type = std::function<R(Args...)>;
	using next = get_rec<type, R, Args...>;
};

-> rec_start<void, int>::type
std::function<void (int)>

-> rec_start<void, int>::next::type
std::function<void (int, std::function<void (int)>)>

-> rec_start<void, int>::next::next::type
std::function<void (int, std::function<void (int, std::function<void (int)>)>)>

-> rec_start<void, int>::next::next::next::type
std::function<void (int, std::function<void (int, std::function<void (int, std::function<void (int)>)>)>)>
Kuzy ★★★
()
Последнее исправление: Kuzy (всего исправлений: 1)
Ответ на: комментарий от staseg

с++, с++11
Но хочется странного^W обойтись без написания классов.

Убирай тогда теги C++, C++11, странный ты наш.

comp00 ★★★★
()

Всем спасибо за участие. В общем даже чисто на шаблонах эта штука не работает.

template<typename T>
void foo(T f, int a){}

template<typename T>
void bar(T f, int a){
    return foo(f, a);
}

Извне попытка вызова bar опять заканчивается бесконечным описанием нужного типа шаблона foo. Попытка прикрутить decltype также ни к чему не привела. Как тут правильно заметили, Шарик упоролся в рекурсивный тип, который С++ не умеет.

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

staseg ★★★★★
() автор топика
Последнее исправление: staseg (всего исправлений: 1)

Очень хотелось бы ознакомится со случаями, когда такие конструкции нужны.

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