Boost logo

Boost :

Subject: Re: [boost] [result_of] Allow result_of to work with C++11 lambdas
From: Nathan Crookston (nathan.crookston_at_[hidden])
Date: 2013-04-12 17:00:39


Hi Mathias,

Mathias Gaunard wrote:

> On 10/04/13 19:43, Nathan Crookston wrote:
>
>> Hi Mathias,
>>
>> Mathias Gaunard wrote:
>>
>> I personally have my own implementation of result_of which does this. My
>>> implementation is also simpler, compiles faster, is optionally optimized
>>> for compilers with variadic templates (also supports compilers with
>>> decltype but no variadic templates), has preprocessing support, and has
>>> the
>>> added benefit that result_of<Sig>::type is only defined if Sig is
>>> callable.
>>>
>>>
>> Sounds pretty slick. Is this in NT2, or just in some other code you have?
>>
>
> Yes. I've found that boost::result_of is often a performance bottleneck.
> Unfortunately the code in Boost is not as simple as it could be; it
> instantiates way too many templates, I suppose for legacy purposes.
> My version could probably still be improved too.
>
> I actually gave this a try with some code that used to cause the
decltype-based boost::result_of problems. It worked well, not matter which
preprocessor symbols I defined. The code and the later fix were both
provided by Eric Niebler, btw (I made minor modifications).

#define USE_RESULT_OF
//#define BOOST_RESULT_OF_USE_DECLTYPE
#define BOOST_RESULT_OF_USE_TR1

#ifndef USE_NT2_RESULT_OF
# include <boost/utility/result_of.hpp>
namespace ro = boost;
#else
# include <boost/dispatch/meta/result_of.hpp>
namespace ro = boost::dispatch::meta;
#endif
#include <utility>

template <typename T>
T const& cref();

template <typename T>
T& ref();

template <typename F, typename Arg>
  typename ro::result_of<F(Arg const&)>::type
  invoke(F f, Arg const& arg)
{
  return f(arg);
}

template <typename F, typename Arg>
  typename ro::result_of<F(Arg&)>::type
  invoke(F f, Arg& arg)
{
  return f(arg);
}

///////////////////////////////////////////////////////////////////////////////
// Client code
///////////////////////////////////////////////////////////////////////////////
#include <iostream>

int foo(int& i)
{
  std::cout << i << std::endl;
  return i;
}

int main()
{
  int i = 123;
  invoke(foo, i);
}

In short, your implementation seems to work well for every tricky case I
tried. Do you perchance have metrics on the difference in # of
instantiations, or compile time? I'm just curious.

Thanks,
Nate


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk