Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > result_of функтора из шаблона


Автор: borisbn 28.1.2013, 14:14
Здравствуйте!
Следующий код
Код
template< class F >
auto foo( F f ) -> typename std::result_of< F >::type {}

void some(){}

int main() {
   foo( some );
}

выдаёт ошибку
Цитата
error: no matching function for call to 'foo(void (&)())'
invalid use of incomplete type 'class std::result_of<void (*)()>'

заменить определение ф-ции foo на такое
Код
template< class F >
auto foo( F f ) -> decltype( f() ) {}

нельзя, т.к. в вызове f() могут быть параметры. Дело в том, что ф-ция foo сама с f ничего не делает, а передаёт "дальше" и ей не нужно знать о наличии и количестве аргументов.
Подскажите, пожалуйста, как при помощи std::result_of (или м.б. std::function) узнать тип возвращаемого значения функтора f.
Спасибо.

http://liveworkspace.org/code/vd5op$16 <--- самый простой вариант, который не работает
http://liveworkspace.org/code/vd5op$19 <--- вариант, который мне, собственно, нужен

Автор: mes 28.1.2013, 18:24
Цитата(borisbn @  28.1.2013,  13:14 Найти цитируемый пост)
нельзя, т.к. в вызове f() могут быть параметры. Дело в том, что ф-ция foo сама с f ничего не делает, а передаёт "дальше" и ей не нужно знать о наличии и количестве аргументов.

 smile 

Цитата(borisbn @  28.1.2013,  13:14 Найти цитируемый пост)
самый простой вариант, который не работает

забыты скобки..

Цитата(borisbn @  28.1.2013,  13:14 Найти цитируемый пост)
вариант, который мне, собственно, нужен 

http://liveworkspace.org/code/3Wb7bl$3


Автор: borisbn 28.1.2013, 18:39
Цитата(mes @  28.1.2013,  18:24 Найти цитируемый пост)
забыты скобки..

я не забыл, а убрал их, т.к. если сделать так
Код
auto foo( F f ) -> typename std::result_of< F() >::type {}

то тогда нельзя будет сделать так
Код
void some( int /* <------- */ );
foo( some );


по поводу второго варианта: мне не нужно вызывать f( ff() ), мне нужно передать их "дальше". Дело в том, что ff может быть объявлена как void some(); и тогда эта конструкция
Код
result_of< F( decltype( ff() ) ) >

работать не будет.

В общем-то я уже сделал по-другому и всё заработало, но захотелось узнать, можно ли при помощи result_of вытащить return_type функтора, про аргументы которого ничего не известно...

Добавлено через 4 минуты и 29 секунд
Может как-то class ... Args заюзать... вроде ж они могут быть пустыми... Я работу с вариадиками ещё плохо знаю

Автор: mes 28.1.2013, 18:52
Цитата

мне нужно передать их "дальше"

непонятно, что есть "дальше" ..вполне возможно, что  у него и надо спрашивать о возвращаемом типе..

Цитата(borisbn @  28.1.2013,  17:39 Найти цитируемый пост)
 при помощи result_of вытащить return_type функтора, про аргументы которого ничего не известно

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

Цитата(borisbn @  28.1.2013,  17:39 Найти цитируемый пост)
 можно ли 

если функтор соответствует концепции функтора, то по хорошему у него дожно быть result_type 


Цитата(borisbn @  28.1.2013,  17:39 Найти цитируемый пост)
Может как-то class ... Args заюзать... вроде ж они могут быть пустыми...

пустыми могут.. но пока непонятно зачем нужна ваша "прокся" ..

Автор: volatile 28.1.2013, 23:58
А если так:
Код

// где нибудь повыше...
template <typename F, typename FF>
struct result_type
{ typedef typename std::result_of <F (typename std::result_of <FF()>::type)>::type type; };

template <typename F>
struct result_type <F, void (*)()>
{ typedef typename std::result_of <F ()>::type type; };

// ------------------------------------------------
// ваша функция начинаецца здесь:
template <typename F, typename FF>
auto foo (F f, FF ff) -> typename result_type <F,FF>::type 
{
   // ...
}

Если ничо не напутал, то вроде удовлетворяет условиям озвученным во второй вашей ссылке LWS
Цитата(borisbn @  28.1.2013,  14:14 Найти цитируемый пост)
вариант, который мне, собственно, нужен 


Автор: volatile 29.1.2013, 03:39
Цитата(volatile @  28.1.2013,  23:58 Найти цитируемый пост)
удовлетворяет условиям озвученным во второй вашей ссылке 

Это то да, только там есть одна засада.
Оно не будет работать с функц.объектами, только с функциями.
Вот это будет работать и тем и с другим:

Код

template <typename F, typename T>
struct result_type
{ typedef typename std::result_of <F(T)>::type type; };

template <typename F>
struct result_type <F, void>
{ typedef typename std::result_of <F()>::type type; };

// ваша функция начинаецца здесь:
template <typename F, typename FF>
auto foo (F f, FF ff) -> typename result_type <F, typename std::result_of <FF()>::type>::type
{
   // ...
}

Автор: borisbn 29.1.2013, 09:53
Цитата(mes @  28.1.2013,  18:52 Найти цитируемый пост)
вполне возможно, что  у него и надо спрашивать о возвращаемом типе..

так и сделал))

Цитата(mes @  28.1.2013,  18:52 Найти цитируемый пост)
если функтор соответствует концепции функтора, то по хорошему у него дожно быть result_type 

тогда нельзя просто функцию подставить

Цитата(volatile @  29.1.2013,  03:39 Найти цитируемый пост)
Вот это будет работать и тем и с другим:

хммм... заманчиво. спасибо.

Цитата(mes @  28.1.2013,  18:52 Найти цитируемый пост)
 пока непонятно зачем нужна ваша "прокся" ..

вот такую штуку хотел замутить - http://liveworkspace.org/code/3eIS41$0
сначала думал чтобы run в trailing return возвращал тип, возвращаемый Waiter'ом, но потом понял, что
Цитата(mes @  28.1.2013,  18:52 Найти цитируемый пост)
вполне возможно, что  у него и надо спрашивать о возвращаемом типе..

))

Всем спасибо. Закрываю.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)