BOOST_RESULT_OF_USE_DECLTYPE not default on C++11 compilers

At least on GCC 4.6 in C++0x (C++11) mode, BOOST_RESULT_OF_USE_DECLTYPE is not set by default, preventing classes such as boost::transform_iterator from working on built-in lambda expressions. Is there a reason that the use of decltype is not on by default for compilers that support it, perhaps with a flag to force emulation mode (like Boost.Move supports)? -- Jeremiah Willcock

On 1/25/2012 6:42 PM, Jeremiah Willcock wrote:
At least on GCC 4.6 in C++0x (C++11) mode, BOOST_RESULT_OF_USE_DECLTYPE is not set by default, preventing classes such as boost::transform_iterator from working on built-in lambda expressions. Is there a reason that the use of decltype is not on by default for compilers that support it, perhaps with a flag to force emulation mode (like Boost.Move supports)?
It's not the default because when we made it the default, all heck broke loose. Partly it was because of buggy libraries that returned a different type from operator() than their nested result<> template declared. Partly, it was due to a bug in the specification of decltype that was only resolved in closing minutes with the adoption of N3276[*]. And partly it is because of continuing non-compliance of compilers that don't property implement N3276. We now have a boost feature macro for detecting this particular form of non-compliance (BOOST_NO_DECLTYPE_N3276), so we can try conditionally enabling decltype-based result_of again. But we'd still need to fix the broken libraries. And let's not kid ourselves ... if it can break boost libraries, it can break end-user code too. The potential for downstream havoc is huge. That said, I still believe it's the right thing to do. [*] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Wed, 25 Jan 2012, Eric Niebler wrote:
On 1/25/2012 6:42 PM, Jeremiah Willcock wrote:
At least on GCC 4.6 in C++0x (C++11) mode, BOOST_RESULT_OF_USE_DECLTYPE is not set by default, preventing classes such as boost::transform_iterator from working on built-in lambda expressions. Is there a reason that the use of decltype is not on by default for compilers that support it, perhaps with a flag to force emulation mode (like Boost.Move supports)?
It's not the default because when we made it the default, all heck broke loose. Partly it was because of buggy libraries that returned a different type from operator() than their nested result<> template declared. Partly, it was due to a bug in the specification of decltype that was only resolved in closing minutes with the adoption of N3276[*]. And partly it is because of continuing non-compliance of compilers that don't property implement N3276.
Would it be possible to use decltype to at least handle C++11 lambdas (which are the one case where normal result_of is broken)? Is there a type trait to detect those? -- Jeremiah Willcock

Jeremiah Willcock
On Wed, 25 Jan 2012, Eric Niebler wrote:
On 1/25/2012 6:42 PM, Jeremiah Willcock wrote:
At least on GCC 4.6 in C++0x (C++11) mode, BOOST_RESULT_OF_USE_DECLTYPE is not set by default, preventing classes such as boost::transform_iterator from working on built-in lambda expressions. Is there a reason that the use of decltype is not on by default for compilers that support it, perhaps with a flag to force emulation mode (like Boost.Move supports)?
It's not the default because when we made it the default, all heck broke loose. Partly it was because of buggy libraries that returned a different type from operator() than their nested result<> template declared. Partly, it was due to a bug in the specification of decltype that was only resolved in closing minutes with the adoption of N3276[*]. And partly it is because of continuing non-compliance of compilers that don't property implement N3276.
Would it be possible to use decltype to at least handle C++11 lambdas (which are the one case where normal result_of is broken)? Is there a type trait to detect those?
-- Jeremiah Willcock
As a template argument a lambda is indistinguishable from any other functor (it may also have a conversion to a function pointer), so I don't think this is possible. You can try to turn the feature on by defining the macro yourself (with Boost.Config) and check if anything breaks. Your users however will be in for nice surprise if they include your headers and get a C++11 result_of which breaks boost libraries that they might include themselves. -- Philipp Moeller

On Thu, 26 Jan 2012, Philipp Moeller wrote:
Jeremiah Willcock
writes: On Wed, 25 Jan 2012, Eric Niebler wrote:
On 1/25/2012 6:42 PM, Jeremiah Willcock wrote:
At least on GCC 4.6 in C++0x (C++11) mode, BOOST_RESULT_OF_USE_DECLTYPE is not set by default, preventing classes such as boost::transform_iterator from working on built-in lambda expressions. Is there a reason that the use of decltype is not on by default for compilers that support it, perhaps with a flag to force emulation mode (like Boost.Move supports)?
It's not the default because when we made it the default, all heck broke loose. Partly it was because of buggy libraries that returned a different type from operator() than their nested result<> template declared. Partly, it was due to a bug in the specification of decltype that was only resolved in closing minutes with the adoption of N3276[*]. And partly it is because of continuing non-compliance of compilers that don't property implement N3276.
Would it be possible to use decltype to at least handle C++11 lambdas (which are the one case where normal result_of is broken)? Is there a type trait to detect those?
-- Jeremiah Willcock
As a template argument a lambda is indistinguishable from any other functor (it may also have a conversion to a function pointer), so I don't think this is possible.
You can try to turn the feature on by defining the macro yourself (with Boost.Config) and check if anything breaks. Your users however will be in for nice surprise if they include your headers and get a C++11 result_of which breaks boost libraries that they might include themselves.
So far I'm using a -D on the compile line to turn it on; luckily, the code I'm using this in is an application, so I don't need to worry about people including these files yet. -- Jeremiah Willcock

Jeremiah Willcock wrote:
On 1/25/2012 6:42 PM, Jeremiah Willcock wrote:
At least on GCC 4.6 in C++0x (C++11) mode, BOOST_RESULT_OF_USE_DECLTYPE is not set by default, preventing classes such as boost::transform_iterator from working on built-in lambda expressions. <snip> So far I'm using a -D on the compile line to turn it on;
BOOST_RESULT_OF_USE_DECLTYPE might break some codes of Boost,
so how about wrapping a function object without tr1 result_of support into
a tr1 function object (i.e. a function object with tr1 result_of support)?
This approach enables us to use transform_iterator with C++11 lambda
without defining BOOST_RESULT_OF_USE_DECLTYPE.
I just wrote a code which wraps into a tr1 function object. Additionally,
I made wrapped functors to be DefaultConstructible and CopyAssignable.
(Since C++11 lambda is not DefaultConstructible nor CopyAssignable,
transform_iterator with it is not a "decent" iterator. Like oven::regular,
the wrapper solves this problem.)
Here is a code:
(Complete code is attached in this mail)
template <typename Func>
class tr1_functor
{
public:
// tr1 result_of support
template <typename Sig>
struct result;
template

Jeremiah Willcock
At least on GCC 4.6 in C++0x (C++11) mode, BOOST_RESULT_OF_USE_DECLTYPE is not set by default, preventing classes such as boost::transform_iterator from working on built-in lambda expressions. Is there a reason that the use of decltype is not on by default for compilers that support it, perhaps with a flag to force emulation mode (like Boost.Move supports)?
-- Jeremiah Willcock
I noticed the same. Although gcc's decltype has been partially broken, at least on gcc, and can sometimes have strange effects when used with `result_of`. (I think this actually used to be a bug in the draft.) This situation would have to be resolved in Boost.Config or with a `result_of` specific solution. -- Philipp Moeller

Jeremiah Willcock wrote:
Is there a reason that the use of decltype is not on by default for compilers that support it, perhaps with a flag to force emulation mode (like Boost.Move supports)?
Aside from the type-completeness problem of old C++0x decltype,
there is another type of breakage caused by incorrect support of the
traditional result_of protocol or incorrect usage of result_of.
Some codes using Boost.Fusion or Boost.Phoenix failed to compile with
BOOST_RESULT_OF_USE_DECLTYPE. The reason for the compile error is that
many metafunctions have `struct result` but they do not have corresponding
function call operators.
http://thread.gmane.org/gmane.comp.parsers.spirit.general/24027
https://svn.boost.org/trac/boost/ticket/5687
So we should proceed gradually even if N3276-decltype become available.
As a first step, Daniel already made by updating the documentation.
The documentation on trunk says:
In a future release, BOOST_RESULT_OF_USE_DECLTYPE may be enabled
by default on compilers that support decltype, so if you use the above
protocol please take care to ensure that the result_type and
result<> members accurately represent the result type.
If you wish to continue to use the protocol on compilers that
support decltype, use boost::tr1_result_of, which is also defined
in
participants (4)
-
Eric Niebler
-
Jeremiah Willcock
-
Michel Morin
-
Philipp Moeller