Note: Assuming 3 categories of compiler, numbered for simplicity below. *1 No decltype *2. Partial decltype support (VC10, current g++ & earlier clang w/ std=c++0x) *3. Full decltype support (recent clang only) Jeffrey Lee Hellrung, Jr. wrote:
Eric Niebler wrote:
Jeffrey Lee Hellrung, Jr. wrote:
Maybe this is what you did, so I might not be suggesting something new, but... Perhaps boost::result_of could have an extra conditional logic branch added to it: - If F::result_type exists, return F::result_type; - Else: - If BOOST_NO_CXX11_DECLTYPE, return F::result< F ( Args... ) > - Else, if F::result<> exists, return F::result< F ( Args... ) > - Else return decltype( declval<F>() ( declval< Args >()... ) )
C++11 defines exactly what result_of does, as did the TR1 spec before it. Making boost::result_of do something different would be surprising, IMO.
If you want to use C++11 lambdas with boost::result_of, the most portable solution is with an adapter, as has been suggested elsewhere in this thread. Not ideal, but it works.
I'm only suggesting to extend result_of for C++11 lambdas (and, incidentally, other callable types) when result_of wouldn't know what to do otherwise. Do you mean it would be surprising for result_of to work when it would be expected to fail? Maybe there's something subtle I'm missing here.
I'm also curious what would be surprising -- if TR1 result_of fails to deduce the result_type it causes a hard error, I believe. It may be surprising that code works on *2 but not *1; I don't see that being different than code which works on *3 not working on *2 & *1 currently. I think I was more surprised by the errors when I first tried using lambdas with boost::result_of than I would have been if it had just worked ;).
I'm supposing in this, of course, that there are compilers which support lambdas and have some form of decltype sufficient for lambdas but insufficient to be the primary implementation of result_of (i.e., must use TR1-style for the primary implementation). That's quite a few compilers presently, right?
I think if you want strictly conforming TR1 or C++11 result_of, you should define the appropriate macro -- otherwise you already get compiler-specific behavior, based on each compiler's capability. Assuming no explicit choice, I think a hybrid behavior, specific to *2, which only kicks in when TR1 result_of wouldn't cause issues where there were none before, would it? I can also see the value of implementing only TR1 and C++11 result_of -- a good deal of thought and discussion went into those documents. (As an aside, this is the second time today on this list I feel I've argued for pragmatism over purity. This is not common.) Thanks, Nate