Re: [boost] [utility/result_of] decltype-based implementation breaking valid code on msvc-10

Eric Niebler wrote:
I suspect the real problem is in a buggy implementation of decltype on msvc-10. For the upcoming boost release, I suggest that we stick with the non-decltype implementation of result_of on msvc-10, or risk massively breaking users' code, not to mention proto, spirit and xpressive on that compiler.
MSVC10 isn't even released yet. Why bother with a non-stable compiler?
I start having a bit of experience with decltype and VC compilers (sigh) through my eUML front-end for MSM and I can give you one reason: because it's probably not just VC10. I have here and there this problem (and others) with VC9 too. It might just happen in different conditions. Christophe

On 4/6/2010 12:28 PM, Christophe Henry wrote:
I start having a bit of experience with decltype and VC compilers (sigh) through my eUML front-end for MSM and I can give you one reason: because it's probably not just VC10. I have here and there this problem (and others) with VC9 too. It might just happen in different conditions.
This is NOT the same issue. VC9 does not have the decltype keyword. We're not talking about typeof emulation. Please don't take us off-topic. The issue is whether the decltype keyword is too broken on VC10 to define BOOST_NO_DECLTYPE. I think it /may/ be, so we should define it just to be safe, at least for 1.43. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On 4/6/2010 12:49 PM, Eric Niebler wrote:
The issue is whether the decltype keyword is too broken on VC10 to define BOOST_NO_DECLTYPE. I think it /may/ be, so we should define it just to be safe, at least for 1.43.
Actually, I may have been too hasty. I notice the same behavior on recent gcc builds. That is, the following program causes both vc10 and gcc in std=c++0x mode to run out of heap space. template<class T> struct S; template<class X, class Y> struct pair {}; template<class T> S<T> wrap(T) { return 0; } template<class T> struct S { S(int = 0) {} // The following use of decltype causes the compiler to blow up: decltype(wrap(pair<T,T>())) foo() { return wrap(pair<T,T>()); } // The following, which should be equivalent, compiles without // problem: //S<pair<T,T> > foo() { return wrap(pair<T,T>()); } }; int main() { S<int> s; } If these are both conforming implementations of decltype, that's bad news. It means that std::result_of has a significant and unfortunate change of behavior from tr1::result_of and boost::result_of, and also means that decltype cannot be safely used in all contexts. I think we need a decltype expert to weigh in on this. I may bring the issue up with the std committee. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler wrote:
Actually, I may have been too hasty. I notice the same behavior on recent gcc builds. That is, the following program causes both vc10 and gcc in std=c++0x mode to run out of heap space.
template<class T> struct S;
template<class X, class Y> struct pair {};
template<class T> S<T> wrap(T) { return 0; }
template<class T> struct S { S(int = 0) {}
// The following use of decltype causes the compiler to blow up: decltype(wrap(pair<T,T>())) foo() { return wrap(pair<T,T>()); }
This is a CWG question. I don't think that the compilers need to instantiate the definition of S<pair<int,int>> from within the decltype, but it appears that they do, and the standard may well require them to. The other unevaluated context, sizeof, would instantiate because it needs the size, and if decltype shares the same code, it will too.

On Tue, Apr 6, 2010 at 7:53 PM, Peter Dimov <pdimov@pdimov.com> wrote:
Eric Niebler wrote:
Actually, I may have been too hasty. I notice the same behavior on recent gcc builds. That is, the following program causes both vc10 and gcc in std=c++0x mode to run out of heap space.
template<class T> struct S;
template<class X, class Y> struct pair {};
template<class T> S<T> wrap(T) { return 0; }
template<class T> struct S { S(int = 0) {}
// The following use of decltype causes the compiler to blow up: decltype(wrap(pair<T,T>())) foo() { return wrap(pair<T,T>()); }
This is a CWG question. I don't think that the compilers need to instantiate the definition of S<pair<int,int>> from within the decltype, but it appears that they do, and the standard may well require them to. The other unevaluated context, sizeof, would instantiate because it needs the size, and if decltype shares the same code, it will too.
I just took a closer look at this. I ran gcc on Eric's example for 30 minutes without ICE, but it never halted. I got an error "invalid use of incomplete type" on a more minimal example. template<class T> struct S; template<class T> S<T> wrap(T) { return 0; } template<class T> struct S { typedef decltype(wrap(T())) type; // error }; int main() { S<int> s; } I believe the error is in compliance with the draft standard. N3092 7.1.6.2.4 states: "The type denoted by decltype(e) is defined as follows: ... if e is a function call (5.2.2) or an invocation of an overloaded operator (parentheses around e are ignored), decltype(e) is the return type of the statically chosen function;" 5.2.2.3 states: "The type of the function call expression is the return type of the statically chosen function (i.e., ignoring the virtual keyword), even if the type of the function actually called is different. This type shall be a complete object type, a reference type or the type void." So, it seems the draft requires compilers to reject code taking decltype of an incomplete type. Daniel Walker

On 4/6/2010 6:22 PM, Daniel Walker wrote:
7.1.6.2.4 states:
"The type denoted by decltype(e) is defined as follows: ... if e is a function call (5.2.2) or an invocation of an overloaded operator (parentheses around e are ignored), decltype(e) is the return type of the statically chosen function;"
5.2.2.3 states:
"The type of the function call expression is the return type of the statically chosen function (i.e., ignoring the virtual keyword), even if the type of the function actually called is different. This type shall be a complete object type, a reference type or the type void."
So, it seems the draft requires compilers to reject code taking decltype of an incomplete type.
Ouch. The implication is that we can't sub the TR1 implementation of result_of with the C++0x implementation without causing some valid code to break. That's terrible. Let's hope this is just an oversight. I'm following up with CWG. In the mean time, what are the chances of backing out the decltype-based implementation of boost::result_of completely (until we have a better plan)? -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Tue, Apr 6, 2010 at 11:50 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/6/2010 6:22 PM, Daniel Walker wrote:
7.1.6.2.4 states:
"The type denoted by decltype(e) is defined as follows: ... if e is a function call (5.2.2) or an invocation of an overloaded operator (parentheses around e are ignored), decltype(e) is the return type of the statically chosen function;"
5.2.2.3 states:
"The type of the function call expression is the return type of the statically chosen function (i.e., ignoring the virtual keyword), even if the type of the function actually called is different. This type shall be a complete object type, a reference type or the type void."
So, it seems the draft requires compilers to reject code taking decltype of an incomplete type.
Ouch. The implication is that we can't sub the TR1 implementation of result_of with the C++0x implementation without causing some valid code to break. That's terrible. Let's hope this is just an oversight. I'm following up with CWG.
In the mean time, what are the chances of backing out the decltype-based implementation of boost::result_of completely (until we have a better plan)?
After considering this for a while, I believe there is an argument in support of the current decltype specification, at least with respect to result_of. result_of is supposed to give the type of the result of a function call, i.e. the type of a function call expression. A call expression cannot have an incomplete type. So, result_of cannot have an incomplete type. Perhaps, Eric has identified a need for a new type specifier, say, incomplete_decltype. If we have a complete decltype, it would make sense to have an incomplete one also. However, if we are to maintain the semantics of result_of as the type of a call expression, then result_of<>::type should be a complete type. Historically, result_of could determine the type of a call expression given a function pointer or reference but could not determine the type given a function object. To get around this problem, a protocol was specified to give users a way to advertise the result type of their function objects. However, this is a fragile affair, since the behavior of result_of depends on the user's conformance to the intention of the protocol. For example, if the user advertises a type other than the result of the call expression, such as an incomplete type, then result_of would no longer give the type of the call expression. The current draft standard resolves this problem by requiring the compiler to deduce the type of the call expression rather than relying on the user to advertise it. Consequentially, code that used the previous TR1 protocol to advertise false result types will be invalid. This is true for incomplete types, but there are other examples as well. Consider the following #include <string> #include <boost/static_assert.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/utility/result_of.hpp> const char* f() { return "hello world"; } struct functor { // note: the result type and result_type are not the same typedef std::string result_type; const char* operator()() const { return f(); } }; template<class T0, class T1> void test(T0 f0, T1 f1); int main() { test(&f, functor()); } template<class T0, class T1> void test(T0 f0, T1 f1) { // in c++98 the type of x1 is not the type of f1(), // but the statements are valid. typename boost::result_of<T0()>::type x0 = f0(); typename boost::result_of<T1()>::type x1 = f1(); // the following is valid in c++0x but not c++98 BOOST_STATIC_ASSERT(( boost::is_same< typename boost::result_of<T0()>::type, typename boost::result_of<T1()>::type >::value )); } So, yes, there are examples of code that are valid in c++98 but not 0x, and vice versa, depending on how closely the type advertised through the legacy protocol matches the actual result type. I think a good solution would be for boost::result_of to offer a backwards compatible mode. So, in c++0x if the user defines, say, BOOST_LEGACY_RESULT_OF then boost::result_of will follow the old TR1 protocol. How does that sound? Daniel Walker

On 4/7/2010 9:21 AM, Daniel Walker wrote:
On Tue, Apr 6, 2010 at 11:50 PM, Eric Niebler<eric@boostpro.com> wrote:
On 4/6/2010 6:22 PM, Daniel Walker wrote:
So, it seems the draft requires compilers to reject code taking decltype of an incomplete type.
Ouch. The implication is that we can't sub the TR1 implementation of result_of with the C++0x implementation without causing some valid code to break. That's terrible. Let's hope this is just an oversight. I'm following up with CWG.
In the mean time, what are the chances of backing out the decltype-based implementation of boost::result_of completely (until we have a better plan)?
After considering this for a while, I believe there is an argument in support of the current decltype specification, at least with respect to result_of. result_of is supposed to give the type of the result of a function call, i.e. the type of a function call expression. A call expression cannot have an incomplete type. So, result_of cannot have an incomplete type. <snip>
Strongly disagree. Decltype (decl-type) yields the "declared type" of an expression. Consider: // found in some header somewhere struct S; S foo(); What is the "declared type" of the expression "foo()"? Obviously, it is S. And if I do: typedef decltype(foo()) s_type; ... I expect s_type to be a simple typedef for S. Nothing here requires S to be complete. The issue is currently under discussion on CWG. Nobody there has yet disagreed that this is surprising, unfortunate and unintended; and someone has already proposed new wording.
I think a good solution would be for boost::result_of to offer a backwards compatible mode. So, in c++0x if the user defines, say, BOOST_LEGACY_RESULT_OF then boost::result_of will follow the old TR1 protocol. How does that sound?
Not good. Proto will need to define that to continue working. That will lead to ODR violations when someone includes utility/result_of.hpp before proto. I still think the best solution is to roll back the decltype changes to boost::result_of until the dust has settled. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Wed, Apr 7, 2010 at 12:46 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/7/2010 9:21 AM, Daniel Walker wrote:
After considering this for a while, I believe there is an argument in support of the current decltype specification, at least with respect to result_of. result_of is supposed to give the type of the result of a function call, i.e. the type of a function call expression. A call expression cannot have an incomplete type. So, result_of cannot have an incomplete type.
<snip>
Strongly disagree. Decltype (decl-type) yields the "declared type" of an expression. Consider:
Not to be pedantic, but call expressions don't exactly have a single "declared type." Their type is determined dynamically by the compiler according to the context in which they are evaluated. The same call expression may have different types in different context.
// found in some header somewhere struct S; S foo();
What is the "declared type" of the expression "foo()"? Obviously, it is S.
It might seem so at first, but consider: struct S; S foo(int); int foo(S); The type of the call expression foo(x) depends on which function is statically chosen after overload resolution. Overload resolution may not succeed unless/until S is complete.
And if I do:
typedef decltype(foo()) s_type;
... I expect s_type to be a simple typedef for S. Nothing here requires S to be complete.
Overload resolution may require S to be complete, in some circumstance at least. Of course, if S is not complete, prototypes using S could be dropped from the overload list, but in any case, I believe the decltype of a call expression would be complete after overload resolution. Not sure about that though.
The issue is currently under discussion on CWG. Nobody there has yet disagreed that this is surprising, unfortunate and unintended; and someone has already proposed new wording.
Unfortunately, I don't have time to participate in the CWG discussion, so I'll just comment here. Let us know how things turn out. I'm sure the confusion will be resolved. Daniel Walker

AMDG Daniel Walker wrote:
// found in some header somewhere struct S; S foo();
What is the "declared type" of the expression "foo()"? Obviously, it is S.
It might seem so at first, but consider:
struct S; S foo(int); int foo(S);
The type of the call expression foo(x) depends on which function is statically chosen after overload resolution. Overload resolution may not succeed unless/until S is complete.
But the completeness of S only affects overload resolution when it's used as an argument. The fact that the argument of one overload is the same as the result of another is irrelevant, IMHO. In Christ, Steven Watanabe

On Thu, Apr 8, 2010 at 11:01 AM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
Daniel Walker wrote:
// found in some header somewhere struct S; S foo();
What is the "declared type" of the expression "foo()"? Obviously, it is S.
It might seem so at first, but consider:
struct S; S foo(int); int foo(S);
The type of the call expression foo(x) depends on which function is statically chosen after overload resolution. Overload resolution may not succeed unless/until S is complete.
But the completeness of S only affects overload resolution when it's used as an argument. The fact that the argument of one overload is the same as the result of another is irrelevant, IMHO.
True. I only meant to show that there are circumstance where successful overload resolution may require a complete type. Here's another example that doesn't use function arguments. One could imagine a scenario such as template<class T> typename boost::enable_if< boost::is_pod<T>, T
::type foo();
template<class T> typename boost::disable_if< boost::is_pod<T>, int
::type foo();
Here the type of the expression foo<S>() cannot be determined if S is incomplete. Daniel Walker

AMDG Daniel Walker wrote:
True. I only meant to show that there are circumstance where successful overload resolution may require a complete type. Here's another example that doesn't use function arguments. One could imagine a scenario such as
template<class T> typename boost::enable_if< boost::is_pod<T>, T
::type foo();
template<class T> typename boost::disable_if< boost::is_pod<T>, int
::type foo();
Here the type of the expression foo<S>() cannot be determined if S is incomplete.
Again this isn't *because* S is the return type. It's because it's passed to a template that requires a complete type. In Christ, Steven Watanabe

On Thu, Apr 8, 2010 at 4:52 PM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
Daniel Walker wrote:
True. I only meant to show that there are circumstance where successful overload resolution may require a complete type. Here's another example that doesn't use function arguments. One could imagine a scenario such as
template<class T> typename boost::enable_if< boost::is_pod<T>, T
::type foo();
template<class T> typename boost::disable_if< boost::is_pod<T>, int
::type foo();
Here the type of the expression foo<S>() cannot be determined if S is incomplete.
Again this isn't *because* S is the return type. It's because it's passed to a template that requires a complete type.
Yes, but the type of a call expression is also required to be a complete type. Maybe this isn't a good example either, since, as you point out, overload resolution can't even begin when S is incomplete due to is_pod. But it seems to me the situations are comparable, conceptually at least. But maybe things are changing. decltype allows us to put call expressions in contexts that they could never appear in before, so perhaps the type requirements for call expressions can be loosened in some of these new contexts. Daniel Walker

On 4/7/2010 1:04 PM, Daniel Walker wrote:
On Wed, Apr 7, 2010 at 12:46 PM, Eric Niebler<eric@boostpro.com> wrote:
On 4/7/2010 9:21 AM, Daniel Walker wrote:
After considering this for a while, I believe there is an argument in support of the current decltype specification, at least with respect to result_of. result_of is supposed to give the type of the result of a function call, i.e. the type of a function call expression. A call expression cannot have an incomplete type. So, result_of cannot have an incomplete type.
<snip>
Strongly disagree. Decltype (decl-type) yields the "declared type" of an expression. Consider:
Not to be pedantic, but call expressions don't exactly have a single "declared type." Their type is determined dynamically by the compiler according to the context in which they are evaluated. The same call expression may have different types in different context.
// found in some header somewhere struct S; S foo();
What is the "declared type" of the expression "foo()"? Obviously, it is S.
It might seem so at first, but consider:
struct S; S foo(int); int foo(S);
The type of the call expression foo(x) depends on which function is statically chosen after overload resolution. Overload resolution may not succeed unless/until S is complete.
7.1.6.2/4: "The type denoted by decltype(e) is defined as follows: — if e is ... or if e names a set of overloaded functions, the program is ill-formed;" Note that your program is ill-formed if you try to take the decltype of an overloaded function set. It continues ... "— otherwise, if e is a function call (5.2.2) or an invocation of an overloaded operator (parentheses around e are ignored), decltype(e) is the return type of the statically chosen function" <snip the rest, which is not relevant>
Unfortunately, I don't have time to participate in the CWG discussion, so I'll just comment here. Let us know how things turn out. I'm sure the confusion will be resolved.
So far, it looks like the proposed resolution to allow decltype of functions returning incomplete types is moving forward. Now, I'd like to re-raise the issue of commenting out for now the decltype-based implementation of result_of both on trunk and release. This is time-critical and a blocker for proto, xpressive and spirit on msvc-10, gcc in c++0x mode, and any other compiler that implements decltype. Let's do it on trunk, see what breaks (nothing, I hope) and try to get it in 1.43. We can always revert later. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On 8 April 2010 19:18, Eric Niebler <eric@boostpro.com> wrote:
Now, I'd like to re-raise the issue of commenting out for now the decltype-based implementation of result_of both on trunk and release. This is time-critical and a blocker for proto, xpressive and spirit on msvc-10, gcc in c++0x mode, and any other compiler that implements decltype. Let's do it on trunk, see what breaks (nothing, I hope) and try to get it in 1.43. We can always revert later.
The decltype implementation was only recently merged to release, we can just revert the merge. Daniel

On Thu, Apr 8, 2010 at 2:44 PM, Daniel James <dnljms@gmail.com> wrote:
On 8 April 2010 19:18, Eric Niebler <eric@boostpro.com> wrote:
Now, I'd like to re-raise the issue of commenting out for now the decltype-based implementation of result_of both on trunk and release. This is time-critical and a blocker for proto, xpressive and spirit on msvc-10, gcc in c++0x mode, and any other compiler that implements decltype. Let's do it on trunk, see what breaks (nothing, I hope) and try to get it in 1.43. We can always revert later.
The decltype implementation was only recently merged to release, we can just revert the merge.
I suppose it's fine to revert the merge. Some compilers are already shipping with a std::result_of that implements the current draft standard. So boost::result_of isn't so critical for these users. Daniel Walker

On 8 April 2010 22:08, Daniel Walker <daniel.j.walker@gmail.com> wrote:
I suppose it's fine to revert the merge. Some compilers are already shipping with a std::result_of that implements the current draft standard. So boost::result_of isn't so critical for these users.
OK, result_of is back to its 1.42 state on the release branch. This reverts the fixes for: https://svn.boost.org/trac/boost/ticket/862 https://svn.boost.org/trac/boost/ticket/1310 https://svn.boost.org/trac/boost/ticket/1535 Daniel

On 4/8/2010 3:07 PM, Daniel James wrote:
On 8 April 2010 22:08, Daniel Walker<daniel.j.walker@gmail.com> wrote:
I suppose it's fine to revert the merge. Some compilers are already shipping with a std::result_of that implements the current draft standard. So boost::result_of isn't so critical for these users.
OK, result_of is back to its 1.42 state on the release branch.
Thanks. The change should also be applied to truck, otherwise, those of us who use truck testing to know when to merge things to release won't be getting an accurate picture of things.
This reverts the fixes for:
Support for boost.lambda. This bug is invalid to begin with. Lambda should be changed to support the TR1 result_of protocol (which is standard), not the other way around.
Support for const-qualified function pointers.
Reduce header dependencies. Forgive me if I'm sounding ungrateful, but why did you revert those other changes? They seem useful. We only needed to select the TR1 implementation unconditionally. That's a much smaller change. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Thu, Apr 8, 2010 at 6:51 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/8/2010 3:07 PM, Daniel James wrote:
On 8 April 2010 22:08, Daniel Walker<daniel.j.walker@gmail.com> wrote:
I suppose it's fine to revert the merge. Some compilers are already shipping with a std::result_of that implements the current draft standard. So boost::result_of isn't so critical for these users.
OK, result_of is back to its 1.42 state on the release branch.
Thanks. The change should also be applied to truck, otherwise, those of us who use truck testing to know when to merge things to release won't be getting an accurate picture of things.
This reverts the fixes for:
Support for boost.lambda.
This bug is invalid to begin with. Lambda should be changed to support the TR1 result_of protocol (which is standard), not the other way around.
No, the result_of in this patch can detect the type of any callable object, including those from boost.lambda, in contexts where the type of the call expression is complete. Now, lambda users who would like to query the type of lambda function objects should use their compiler's std::result_of, if it implements any draft of the standard from the past 2 years, or simply roll their own. Daniel Walker

On 4/8/2010 4:25 PM, Daniel Walker wrote:
On Thu, Apr 8, 2010 at 6:51 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/8/2010 3:07 PM, Daniel James wrote:
This reverts the fixes for:
Support for boost.lambda.
This bug is invalid to begin with. Lambda should be changed to support the TR1 result_of protocol (which is standard), not the other way around.
No, the result_of in this patch can detect the type of any callable object, including those from boost.lambda, in contexts where the type of the call expression is complete. Now, lambda users who would like to query the type of lambda function objects should use their compiler's std::result_of, if it implements any draft of the standard from the past 2 years, or simply roll their own.
Hi Daniel, IIUC the fix here for Boost.Lambda was to implement the c++0x result_of on supporting compilers. That's fine -- as long as you accept that a decltype-based result_of is a safe substitute for the TR1 result_of, which I don't. My point above was that this bug should have been closed "Invalid" because it's not a result_of problem. The problem is that Lambda doesn't support the TR1 result_of protocol. This isn't news. The standard response is to use Phoenix. I don't particularly like that answer because ... (a) Phoenix isn't a top-level boost library and is likely to change once we get Phoenix ported to Proto, and (b) Lambda has a big installed user-base who won't benefit from improvements to Phoenix. But all this is a side issue. The real issue is to back out the decltype change (and ONLY the decltype change) to result_of on trunk, and merge the change to release as soon as we get the green light from the regression tests. Let me know if you need a patch for this. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Fri, Apr 9, 2010 at 3:35 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/8/2010 4:25 PM, Daniel Walker wrote:
On Thu, Apr 8, 2010 at 6:51 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/8/2010 3:07 PM, Daniel James wrote:
This reverts the fixes for:
Support for boost.lambda.
This bug is invalid to begin with. Lambda should be changed to support the TR1 result_of protocol (which is standard), not the other way around.
No, the result_of in this patch can detect the type of any callable object, including those from boost.lambda, in contexts where the type of the call expression is complete. Now, lambda users who would like to query the type of lambda function objects should use their compiler's std::result_of, if it implements any draft of the standard from the past 2 years, or simply roll their own.
Hi Daniel,
IIUC the fix here for Boost.Lambda was to implement the c++0x result_of on supporting compilers. That's fine -- as long as you accept that a decltype-based result_of is a safe substitute for the TR1 result_of, which I don't.
That's fine, but safe is a relative term. Other users might have a higher tolerance for the risks of being an early adopter. I think boost can accommodate both sorts of users. If you compile with -std=c++0x, you already know your moving into a new world, and I think boost should be there waiting.
My point above was that this bug should have been closed "Invalid" because it's not a result_of problem. The problem is that Lambda doesn't support the TR1 result_of protocol. <snip>
This is a problem in c++98 and I agree with your solution for c++98 (and the long-term path from Proto to Phoenix to Lambda). But in c++0x the TR1 result_of protocol is superseded. It just so happens that fixing the "bug" of boost/lambda compatibility is trivial in c++0x, even though it's complicated in c++98. This patch fixes the bug in c++0x. Daniel Walker

On 8 April 2010 23:51, Eric Niebler <eric@boostpro.com> wrote:
Thanks. The change should also be applied to truck, otherwise, those of us who use truck testing to know when to merge things to release won't be getting an accurate picture of things.
That's probably true, although utility hasn't been the same on trunk and release for a long time, I merged the result_of changes mainly to fix that. I'll leave it Daniel Walker to decide what he wants to go from here.
Forgive me if I'm sounding ungrateful, but why did you revert those other changes? They seem useful. We only needed to select the TR1 implementation unconditionally. That's a much smaller change.
To go back to the last state that's known to be good, since they were merged together and haven't been tested individually. If we're going to use some of the changes, that should be sorted out on trunk first. And I think I should have been more cautious about merging in the first place. It also made it easier to check that I'd correctly reverted the changes, since changes to the different parts of utility can get mixed up and subversion can sometimes be a bit nutty with merges. Daniel

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 4/8/2010 4:28 PM, Daniel James wrote:
On 8 April 2010 23:51, Eric Niebler <eric@boostpro.com> wrote:
Thanks. The change should also be applied to truck, otherwise, those of us who use truck testing to know when to merge things to release won't be getting an accurate picture of things.
That's probably true, although utility hasn't been the same on trunk and release for a long time, I merged the result_of changes mainly to fix that. I'll leave it Daniel Walker to decide what he wants to go from here.
Daniel? Ideally, we should get the other fixes back, but just comment out the check for BOOST_NO_DECLTYPE and always select the TR1 implementation.
Forgive me if I'm sounding ungrateful, but why did you revert those other changes? They seem useful. We only needed to select the TR1 implementation unconditionally. That's a much smaller change.
To go back to the last state that's known to be good, since they were merged together and haven't been tested individually. If we're going to use some of the changes, that should be sorted out on trunk first.
Agreed. In fact, that's exactly what I suggested here: http://article.gmane.org/gmane.comp.lib.boost.devel/202513.
And I think I should have been more cautious about merging in the first place.
It's probably better in general to merge one change at a time, but I never do that either because it's a PITA. Svn (or svnmerge.py) is too slow. <sigh>
It also made it easier to check that I'd correctly reverted the changes, since changes to the different parts of utility can get mixed up and subversion can sometimes be a bit nutty with merges.
I find svnnmerge.py tends to Just Work as long as you're patient. YMMV. - -- Eric Niebler BoostPro Computing http://www.boostpro.com -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJLv3v2AAoJEAeJsEDfjLbXMQwH/RFAjWBKwf61TJx7J8wN6jWL 4sf3KE40bkvgXsOpFcrmTUoe/IAJf12teXMIrTZpgCvouf/kgDHUIZQX5ech7z1f aSij1ETHOU6kMN6HeGmvS7Mq38hv5wBWoJBO9U+2aXDevX4/b9MLWbC36rt45CZE LWDhJ2XlFcRflczp2uslLIPdu1yCRawyNrtfVNczSk36Pt0fA9U2LE00eLfuGLKc qIQ57mARVy2HccydN79yoHpWKVtj3dY0hA3uSkaVbEKdhhIU34O13F82KRcBLAAX 8s0zP3m5aGhjSIWN/B4jm+Xygjoc26cJ4rJyaiPjZ5Fs9R2mG4/X9f2ojYy+BL0= =iDXo -----END PGP SIGNATURE-----

On Fri, Apr 9, 2010 at 3:11 PM, Eric Niebler <eric@boostpro.com> wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 4/8/2010 4:28 PM, Daniel James wrote:
On 8 April 2010 23:51, Eric Niebler <eric@boostpro.com> wrote:
Thanks. The change should also be applied to truck, otherwise, those of us who use truck testing to know when to merge things to release won't be getting an accurate picture of things.
That's probably true, although utility hasn't been the same on trunk and release for a long time, I merged the result_of changes mainly to fix that. I'll leave it Daniel Walker to decide what he wants to go from here.
Daniel? Ideally, we should get the other fixes back, but just comment out the check for BOOST_NO_DECLTYPE and always select the TR1 implementation.
If it's no problem to merge the other changes to release, that sounds good. But I'd like to leave trunk as is for the time being. We waited until the standards committee voted to accept decltype and the new result_of before adding the implementation to trunk. I think we should wait for the committee to respond to our experience before taking a step backwards. Actually, I think it would be nice in the future if boost::result_of kept in close synch with the draft as it's finalized. In that spirit, here's another possible solution for the current release that may address your concerns Eric, without inhibiting other users. Boost packages/distributes a TR1 implementation. Why not copy the TR1 result_of implementation to Boost.TR1? That way Proto and anyone else who designed for TR1 could rely on Boost.TR1 result_of to remain as it is. Meanwhile, boost::result_of could offer c++0x compliance, and eventually, other new features. If this sounds reasonable I can put together a patch right away. Daniel Walker

CC'ing John Maddock because this now involves Boost.TR1. On 4/9/2010 1:48 PM, Daniel Walker wrote:
On Fri, Apr 9, 2010 at 3:11 PM, Eric Niebler <eric@boostpro.com> wrote:
Ideally, we should get the other fixes back, but just comment out the check for BOOST_NO_DECLTYPE and always select the TR1 implementation.
If it's no problem to merge the other changes to release, that sounds good. But I'd like to leave trunk as is for the time being. We waited until the standards committee voted to accept decltype and the new result_of before adding the implementation to trunk. I think we should wait for the committee to respond to our experience before taking a step backwards.
IIUC, we haven't yet shipped a version of result_of that uses decltype, so this wouldn't be a step backwards. This would merely be deferring the step forward until we can do so more confidently.
Actually, I think it would be nice in the future if boost::result_of kept in close synch with the draft as it's finalized.
That's reasonable, in the absence of time constraints.
In that spirit, here's another possible solution for the current release that may address your concerns Eric, without inhibiting other users. Boost packages/distributes a TR1 implementation. Why not copy the TR1 result_of implementation to Boost.TR1? That way Proto and anyone else who designed for TR1 could rely on Boost.TR1 result_of to remain as it is. Meanwhile, boost::result_of could offer c++0x compliance, and eventually, other new features. If this sounds reasonable I can put together a patch right away.
I like this idea, and it sounds like a good long-term solution. I don't think we have time to try this change out in the 1.43 time-frame, though. I looked at the TR1 stuff, and it looks scarily complicated. It conditionally uses the platform-supplied headers if they're available. The question then becomes whether those headers (over which we have no control) will switch to decltype once it's available. (John?) I like the idea of making a separate TR1-style result_of available to the libraries that need it. Whether it should be part of Boost.TR1 (std::tr1::result_of) or whether it should be part of Boost.Result_of (boost::tr1_result_of or some such) is an open issue, and I don't have strong feelings. My only strong feeling is that we need to decide soon what change to make for 1.43, and it should be a small change. To me, that argues for simply backing out the decltype implementation for 1.43. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Fri, Apr 9, 2010 at 6:39 PM, Eric Niebler <eric@boostpro.com> wrote:
CC'ing John Maddock because this now involves Boost.TR1.
On 4/9/2010 1:48 PM, Daniel Walker wrote:
On Fri, Apr 9, 2010 at 3:11 PM, Eric Niebler <eric@boostpro.com> wrote:
Ideally, we should get the other fixes back, but just comment out the check for BOOST_NO_DECLTYPE and always select the TR1 implementation.
If it's no problem to merge the other changes to release, that sounds good. But I'd like to leave trunk as is for the time being. We waited until the standards committee voted to accept decltype and the new result_of before adding the implementation to trunk. I think we should wait for the committee to respond to our experience before taking a step backwards.
IIUC, we haven't yet shipped a version of result_of that uses decltype, so this wouldn't be a step backwards. This would merely be deferring the step forward until we can do so more confidently.
The decltype result_of isn't on the 1.43 release branch. I believe Daniel James reverted the changes last night. So, as of right now, 1.43 won't ship with the decltype result_of, which is acceptable to me, but I still think we should leave the code on trunk for anyone who uses trunk.
<snip> I looked at the TR1 stuff, and it looks scarily complicated. It conditionally uses the platform-supplied headers if they're available. The question then becomes whether those headers (over which we have no control) will switch to decltype once it's available. (John?)
Good point and fyi, gcc 5.0 does use decltype in it's headers. So, if we want Boost.TR1 to be TR1 on gcc 5.0 we may need to make a change or two. 5.0 was released 2 weeks ago. Daniel Walker

On 4/9/2010 5:31 PM, Daniel Walker wrote:
The decltype result_of isn't on the 1.43 release branch. I believe Daniel James reverted the changes last night.
Yes. He also reverted a bunch of other fixes, which seems unfortunate to me. I can live with that, though.
So, as of right now, 1.43 won't ship with the decltype result_of, which is acceptable to me, but I still think we should leave the code on trunk for anyone who uses trunk.
I think on trunk we should start moving toward whatever solution we feel will be appropriate for 1.44.
fyi, gcc 5.0 does use decltype in it's headers.
You mean gcc-4.5? I see a tr1/functional header there that has an implementation of result_of that doesn't use decltype.
So, if we want Boost.TR1 to be TR1 on gcc 5.0 we may need to make a change or two. 5.0 was released 2 weeks ago.
If Boost.TR1 advertises itself as an implementation of TR1, then it should have an implementation of result_of that doesn't rely on decltype. (Waiting for John to jump in here.) That way, libraries like Proto that need the tr1 behavior (until decltype is fixed) can use std::tr1::result_of from boost/tr1/functional.hpp and forget about it. This should be possible in the 1.44 time frame and is a good long-term solution. In that world, boost::result_of could be free to use decltype or not as appropriate. But to be honest, I don't particularly like the fact that boost::result_of behaves differently depending on whether decltype is available or not -- it hurts code portability -- but utility/result_of is your baby now, and it's your call. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Sat, Apr 10, 2010 at 7:50 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/9/2010 5:31 PM, Daniel Walker wrote:
fyi, gcc 5.0 does use decltype in it's headers.
You mean gcc-4.5? I see a tr1/functional header there that has an implementation of result_of that doesn't use decltype.
Sorry, yeah, 4.5. That's good news that they have a correct tr1/functional header. I didn't notice that at first. However, the regular gcc functional header does use decltype result_of. The two headers use two different namespaces, std::result_of and std::tr1::result_of, which is good. That will prevent folks from inadvertently using one and not the other, and Boost.TR1 will still be able to get TR1 result_of from the gcc headers.
So, if we want Boost.TR1 to be TR1 on gcc 5.0 we may need to make a change or two. 5.0 was released 2 weeks ago.
If Boost.TR1 advertises itself as an implementation of TR1, then it should have an implementation of result_of that doesn't rely on decltype. (Waiting for John to jump in here.) That way, libraries like Proto that need the tr1 behavior (until decltype is fixed) can use std::tr1::result_of from boost/tr1/functional.hpp and forget about it. This should be possible in the 1.44 time frame and is a good long-term solution.
Agreed.
In that world, boost::result_of could be free to use decltype or not as appropriate. But to be honest, I don't particularly like the fact that boost::result_of behaves differently depending on whether decltype is available or not -- it hurts code portability -- but utility/result_of is your baby now, and it's your call.
Well, function objects written for c++0x will only work with TR1 result_of if they use the old, intrusive protocol to specify the (complete) type of the call expression. However, the TR1 protocol is not necessary in c++0x, which is a good thing. But your point is well taken, and I think portability should be an important consideration regarding any future changes. Daniel Walker

On 4/11/2010 9:37 AM, Daniel Walker wrote:
On Sat, Apr 10, 2010 at 7:50 PM, Eric Niebler <eric@boostpro.com> wrote:
If Boost.TR1 advertises itself as an implementation of TR1, then it should have an implementation of result_of that doesn't rely on decltype. (Waiting for John to jump in here.) That way, libraries like Proto that need the tr1 behavior (until decltype is fixed) can use std::tr1::result_of from boost/tr1/functional.hpp and forget about it. This should be possible in the 1.44 time frame and is a good long-term solution.
Agreed.
Note that to make this happen, you'll need to coordinate with John. The way Boost.TR1 works is like this: - If the platform implements <tr1/foo_header>, include it. Otherwise, - Include <boost/foo_header.hpp> and bring boost::foo into the std::tr1 namespace with a using declaration. If boost::result_of sometimes uses decltype, the above won't work because then std::tr1::result_of will sometimes use decltype. It seems to me that <boost/utility/result_of.hpp> should expose a boost::tr1_result_of that can be used by <boost/tr1/result_of.hpp> to get the TR1 behavior regardless of whether decltype exists or not. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On 4/11/2010 12:29 PM, Eric Niebler wrote:
On 4/11/2010 9:37 AM, Daniel Walker wrote:
On Sat, Apr 10, 2010 at 7:50 PM, Eric Niebler <eric@boostpro.com> wrote:
If Boost.TR1 advertises itself as an implementation of TR1, then it should have an implementation of result_of that doesn't rely on decltype. (Waiting for John to jump in here.) That way, libraries like Proto that need the tr1 behavior (until decltype is fixed) can use std::tr1::result_of from boost/tr1/functional.hpp and forget about it. This should be possible in the 1.44 time frame and is a good long-term solution.
Agreed.
Note that to make this happen, you'll need to coordinate with John. The way Boost.TR1 works is like this:
- If the platform implements <tr1/foo_header>, include it. Otherwise, - Include <boost/foo_header.hpp> and bring boost::foo into the std::tr1 namespace with a using declaration.
If boost::result_of sometimes uses decltype, the above won't work because then std::tr1::result_of will sometimes use decltype. It seems to me that <boost/utility/result_of.hpp> should expose a boost::tr1_result_of that can be used by <boost/tr1/result_of.hpp> to get the TR1 behavior regardless of whether decltype exists or not.
I opened a ticket for this (milestone 1.44) and attached a patch: https://svn.boost.org/trac/boost/ticket/4084. I noticed that the decltype change to result_of was causing regression failures in TR1 by making the implementation of TR1's result_of non-compliant. The patch fixes the issue and adds a boost::tr1_result_of. The regression test failures may be more evidence that the change to result_of was a bad idea (as well-intentioned as it may have seemed). This patch may not be the last word on the issue. I'm still uncomfortable with the change to boost::result_of, which is likely to break users' code. Perhaps we could place the new decltype implementation on a compile-time switch (BOOST_RESULT_OF_USE_DECLTYPE?) so that users can opt in. That wouldn't eliminate the need for boost::tr1_result_of or something like it, though. Cheers, -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Sun, Apr 11, 2010 at 5:47 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/11/2010 12:29 PM, Eric Niebler wrote:
On 4/11/2010 9:37 AM, Daniel Walker wrote:
On Sat, Apr 10, 2010 at 7:50 PM, Eric Niebler <eric@boostpro.com> wrote:
If Boost.TR1 advertises itself as an implementation of TR1, then it should have an implementation of result_of that doesn't rely on decltype. (Waiting for John to jump in here.) That way, libraries like Proto that need the tr1 behavior (until decltype is fixed) can use std::tr1::result_of from boost/tr1/functional.hpp and forget about it. This should be possible in the 1.44 time frame and is a good long-term solution.
Agreed.
Note that to make this happen, you'll need to coordinate with John. The way Boost.TR1 works is like this:
- If the platform implements <tr1/foo_header>, include it. Otherwise, - Include <boost/foo_header.hpp> and bring boost::foo into the std::tr1 namespace with a using declaration.
If boost::result_of sometimes uses decltype, the above won't work because then std::tr1::result_of will sometimes use decltype. It seems to me that <boost/utility/result_of.hpp> should expose a boost::tr1_result_of that can be used by <boost/tr1/result_of.hpp> to get the TR1 behavior regardless of whether decltype exists or not.
I opened a ticket for this (milestone 1.44) and attached a patch: https://svn.boost.org/trac/boost/ticket/4084. I noticed that the decltype change to result_of was causing regression failures in TR1 by making the implementation of TR1's result_of non-compliant. The patch fixes the issue and adds a boost::tr1_result_of.
I like the idea and the patch looks good. How do I go about getting it on trunk? I don't believe I have check-in rights.
The regression test failures may be more evidence that the change to result_of was a bad idea (as well-intentioned as it may have seemed). This patch may not be the last word on the issue. I'm still uncomfortable with the change to boost::result_of, which is likely to break users' code. Perhaps we could place the new decltype implementation on a compile-time switch (BOOST_RESULT_OF_USE_DECLTYPE?) so that users can opt in. That wouldn't eliminate the need for boost::tr1_result_of or something like it, though.
Ultimately, boost::result_of should behave as intended whenever possible; i.e. it should evaluate to the type of a call expression. The fact that in c++03 it was possible for result_of to evaluate to a type other than the type of a call expression is a bug. In c++0x, the compiler can detect these situations and report them as errors. That's a good thing. Now, I understand that it's too much to ask before the 1.43 release that boost compile without error or regression in c++0x mode on gcc or msvc, so I agree with sweeping this problem under the rug for this release. But in the future, it is reasonable to expect regressions when porting boost to c++0x. One type of regression will be situations when result_of was evaluated to a type other than the type of the call expression. Usually, this will be due to an unintended programming error, so correcting the problem will be an improvement. Sometimes, it will be due to a quirk of the TR1 protocol; for example, allowing result_of in context where the call expression type is incomplete, as was the case with Proto. Perhaps, result_of is not the best solution in Proto's situation, and Proto should specify return types in its function signatures in some other way... Regardless, given available technology, result_of should evaluate to the type of the call expression; in c++0x the technology is available and result_of should use it. Daniel Walker

On 4/12/2010 8:05 AM, Daniel Walker wrote:
On Sun, Apr 11, 2010 at 5:47 PM, Eric Niebler <eric@boostpro.com> wrote:
I opened a ticket for this (milestone 1.44) and attached a patch: https://svn.boost.org/trac/boost/ticket/4084.
I like the idea and the patch looks good. How do I go about getting it on trunk? I don't believe I have check-in rights.
If you're a library maintainer, you need svn commit permission. I'm not sure who the gate-keeper of svn is these days. Please send a separate message to the list asking for permission. If you want, I can apply this patch. Or John can do it because it touches his code, too.
The regression test failures may be more evidence that the change to result_of was a bad idea (as well-intentioned as it may have seemed). This patch may not be the last word on the issue. I'm still uncomfortable with the change to boost::result_of, which is likely to break users' code. Perhaps we could place the new decltype implementation on a compile-time switch (BOOST_RESULT_OF_USE_DECLTYPE?) so that users can opt in. That wouldn't eliminate the need for boost::tr1_result_of or something like it, though.
Ultimately, boost::result_of should behave as intended whenever possible; i.e. it should evaluate to the type of a call expression. <snip>
This is a strident position ... and wrong. Intention has nothing to do with it. Boost::result_of should behave as *specified*. The current documentation for boost::result_of specify it to use the TR1 result_of protocol. Users have come to rely on it. The TR1 behavior is not a bug. It's a standard. And if you want to talk about *standard* specifications, there are 2 to choose from (or will be soon): TR1 and C++0x. One can be implemented with complete fidelity on every major supported compiler. The other can only be supported on the newest compilers and is still in flux due to a bug in the specification of decltype. I think going with the second is premature, even if you forget about the LOCs you'll break. Intentions and specifications aside, you are now the maintainer of one of the most heavily used and essential pieces of Boost infrastructure. Not breaking code should be a factor in your decisions. If you want to change behavior, you need a migration path. Putting the new (experimental and buggy) behavior on a switch so users can opt in is a reasonable first step. It should be accompanied with documentation, release notes, and an effort to educate boost developers and users about ways to find their portability/migration issues so that their code works with a decltype-based result_of. We may decide to hold here for a few releases, or until vendors start shipping non-broken decltype implementations. Only after folks have had sufficient warning and time to adapt could we think about making decltype the default. Sincerely, -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Mon, Apr 12, 2010 at 1:28 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/12/2010 8:05 AM, Daniel Walker wrote:
On Sun, Apr 11, 2010 at 5:47 PM, Eric Niebler <eric@boostpro.com> wrote:
The regression test failures may be more evidence that the change to result_of was a bad idea (as well-intentioned as it may have seemed). This patch may not be the last word on the issue. I'm still uncomfortable with the change to boost::result_of, which is likely to break users' code. Perhaps we could place the new decltype implementation on a compile-time switch (BOOST_RESULT_OF_USE_DECLTYPE?) so that users can opt in. That wouldn't eliminate the need for boost::tr1_result_of or something like it, though.
Ultimately, boost::result_of should behave as intended whenever possible; i.e. it should evaluate to the type of a call expression. <snip>
This is a strident position ... and wrong. Intention has nothing to do with it. Boost::result_of should behave as *specified*. The current documentation for boost::result_of specify it to use the TR1 result_of protocol. Users have come to rely on it. The TR1 behavior is not a bug. It's a standard.
I don't mean to be stridently wrong. :) Let me try to explain. The boost::result_of documentation says the following: "The class template result_of helps determine the type of a call expression. Given an lvalue f of type F and lvalues t1, t2, ..., tN of types T1, T2, ..., TN, respectively, the type result_of<F(T1, T2, ..., TN)>::type defines the result type of the expression f(t1, t2, ...,tN)." In the strictest sense, this is only true in TR1 if F is a function pointer, function reference or member function pointer. If F is a class type, result_of<F(T1, T2, ..., TN)>::type could be any type and may have nothing to do with the expression f(t1, t2, ...,tN), depending on whether F::result<> meets the "intention" of the specification. result_of is specified to give the type of f(t1, t2, ...,tN). If, for whatever reason, it is not the type of f(t1, t2, ...,tN), then that is a "bug," in some sense. In c++0x, result_of can treat class types the same way as function pointers, function references and member function pointers; i.e. it can give the type of f(t1, t2, ...,tN) for any F, so this sort of bug is no longer possible.
And if you want to talk about *standard* specifications, there are 2 to choose from (or will be soon): TR1 and C++0x. One can be implemented with complete fidelity on every major supported compiler. The other can only be supported on the newest compilers and is still in flux due to a bug in the specification of decltype. I think going with the second is premature, even if you forget about the LOCs you'll break.
Intentions and specifications aside, you are now the maintainer of one of the most heavily used and essential pieces of Boost infrastructure. Not breaking code should be a factor in your decisions. If you want to change behavior, you need a migration path. Putting the new (experimental and buggy) behavior on a switch so users can opt in is a reasonable first step. It should be accompanied with documentation, release notes, and an effort to educate boost developers and users about ways to find their portability/migration issues so that their code works with a decltype-based result_of. We may decide to hold here for a few releases, or until vendors start shipping non-broken decltype implementations. Only after folks have had sufficient warning and time to adapt could we think about making decltype the default.
I agree with the priorities you've expressed, and I'm glad you've pressed the issue here and on CWG. I think we're coming to a better understanding of things, now, and we can continue ironing out these issues after 1.43. Daniel Walker

On 4/12/2010 4:02 PM, Daniel Walker wrote: <snip>
I agree with the priorities you've expressed, and I'm glad you've pressed the issue here and on CWG. I think we're coming to a better understanding of things, now, and we can continue ironing out these issues after 1.43.
Right! And thank you for volunteering to maintain result_of. Your efforts are truly appreciated. One of the things we'll need to work out post-1.43 is if our migration plan is sound. It necessarily means that, until all supported compilers have decltype, boost::result_of will have a split personality: decltype on some platforms, TR1 protocol on others. If we decide that's acceptable, or can't come up with a better alternative, one of the things you as maintainer will have to do is to help people deal with this result_of two-step. That will involve exploring the nasty corner cases, coming up with developer guidelines, educating people, improving the documentation (which at this point is pretty paltry), etc, etc. You may even have to submit patches to other Boost libraries to bring them into compliance with your new guidelines. Of course, the boost community, myself included, are here to help. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler wrote:
That will involve exploring the nasty corner cases, coming up with developer guidelines, educating people, improving the documentation (which at this point is pretty paltry), etc, etc. You may even have to submit patches to other Boost libraries to bring them into compliance with your new guidelines.
jus stepping in as a heavy user of result_of, i wanted to add my 0.02€ on the need of a more elaborated doc for result_of. I had hard time getting coworkers getting used to it because of the laconic documentation. So any effort there will be wonderful.

Note that to make this happen, you'll need to coordinate with John. The way Boost.TR1 works is like this:
- If the platform implements <tr1/foo_header>, include it. Otherwise, - Include <boost/foo_header.hpp> and bring boost::foo into the std::tr1 namespace with a using declaration.
If boost::result_of sometimes uses decltype, the above won't work because then std::tr1::result_of will sometimes use decltype. It seems to me that <boost/utility/result_of.hpp> should expose a boost::tr1_result_of that can be used by <boost/tr1/result_of.hpp> to get the TR1 behavior regardless of whether decltype exists or not.
Nod, I've had to do something similar with some type_traits classes when they changed from TR1 to C++1x. Can someone who understands the issues please work out a patch? Also note that providing an "archived" TR1 version of result_of won't help other Boost code that relies on boost::result_of - some of which may also get imported and/or used by the TR1 lib :-( John.

On 4/12/2010 1:50 AM, John Maddock wrote:
Note that to make this happen, you'll need to coordinate with John. The way Boost.TR1 works is like this:
- If the platform implements <tr1/foo_header>, include it. Otherwise, - Include <boost/foo_header.hpp> and bring boost::foo into the std::tr1 namespace with a using declaration.
If boost::result_of sometimes uses decltype, the above won't work because then std::tr1::result_of will sometimes use decltype. It seems to me that <boost/utility/result_of.hpp> should expose a boost::tr1_result_of that can be used by <boost/tr1/result_of.hpp> to get the TR1 behavior regardless of whether decltype exists or not.
Nod, I've had to do something similar with some type_traits classes when they changed from TR1 to C++1x.
Can someone who understands the issues please work out a patch?
John, I have attached a patch to https://svn.boost.org/trac/boost/ticket/4084. Please look it over and commit it to trunk if you accept it. Daniel Walker, the result_of maintainer, has already approved it. Or just let me know and I'll apply it.
Also note that providing an "archived" TR1 version of result_of won't help other Boost code that relies on boost::result_of - some of which may also get imported and/or used by the TR1 lib :-(
Crap. I guess any component of any TR1 library that depends on result_of will need to come in two flavors. The Boost.TR1 library's version will select the appropriate one. That's ugly. Or we can just say it's a known Boost.TR1 bug and live with it. -- Eric Niebler BoostPro Computing http://www.boostpro.com

John, I have attached a patch to https://svn.boost.org/trac/boost/ticket/4084. Please look it over and commit it to trunk if you accept it. Daniel Walker, the result_of maintainer, has already approved it. Or just let me know and I'll apply it.
I don't pretend to understand the details of result_of, but the TR1 patch is trivial and looks OK. Can you go ahead and commit? Thanks, John.

On 4/13/2010 1:47 AM, John Maddock wrote:
John, I have attached a patch to https://svn.boost.org/trac/boost/ticket/4084. Please look it over and commit it to trunk if you accept it. Daniel Walker, the result_of maintainer, has already approved it. Or just let me know and I'll apply it.
I don't pretend to understand the details of result_of, but the TR1 patch is trivial and looks OK. Can you go ahead and commit?
Done. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Sat, Apr 10, 2010 at 7:50 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/9/2010 5:31 PM, Daniel Walker wrote:
The decltype result_of isn't on the 1.43 release branch. I believe Daniel James reverted the changes last night.
Yes. He also reverted a bunch of other fixes, which seems unfortunate to me. I can live with that, though.
Is it possible in SVN to merge changes related to some tickets but not others? There were three tickets affected. Could the changes from tickets 1310 and 1535 be merged to release without merging the changes from ticket 862? Daniel Walker

On 4/11/2010 9:44 AM, Daniel Walker wrote:
On Sat, Apr 10, 2010 at 7:50 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/9/2010 5:31 PM, Daniel Walker wrote:
The decltype result_of isn't on the 1.43 release branch. I believe Daniel James reverted the changes last night.
Yes. He also reverted a bunch of other fixes, which seems unfortunate to me. I can live with that, though.
Is it possible in SVN to merge changes related to some tickets but not others? There were three tickets affected. Could the changes from tickets 1310 and 1535 be merged to release without merging the changes from ticket 862?
Svn knows nothing about tickets. It only knows about revisions. You can merge individual revisions, or you can forget about merging and just do it by hand. HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Thu, Apr 8, 2010 at 2:18 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/7/2010 1:04 PM, Daniel Walker wrote:
On Wed, Apr 7, 2010 at 12:46 PM, Eric Niebler<eric@boostpro.com> wrote:
On 4/7/2010 9:21 AM, Daniel Walker wrote:
After considering this for a while, I believe there is an argument in support of the current decltype specification, at least with respect to result_of. result_of is supposed to give the type of the result of a function call, i.e. the type of a function call expression. A call expression cannot have an incomplete type. So, result_of cannot have an incomplete type.
<snip>
Strongly disagree. Decltype (decl-type) yields the "declared type" of an expression. Consider:
Not to be pedantic, but call expressions don't exactly have a single "declared type." Their type is determined dynamically by the compiler according to the context in which they are evaluated. The same call expression may have different types in different context.
// found in some header somewhere struct S; S foo();
What is the "declared type" of the expression "foo()"? Obviously, it is S.
It might seem so at first, but consider:
struct S; S foo(int); int foo(S);
The type of the call expression foo(x) depends on which function is statically chosen after overload resolution. Overload resolution may not succeed unless/until S is complete.
7.1.6.2/4: "The type denoted by decltype(e) is defined as follows: — if e is ... or if e names a set of overloaded functions, the program is ill-formed;"
Note that your program is ill-formed if you try to take the decltype of an overloaded function set. It continues ...
"— otherwise, if e is a function call (5.2.2) or an invocation of an overloaded operator (parentheses around e are ignored), decltype(e) is the return type of the statically chosen function"
<snip the rest, which is not relevant>
If overload resolution succeeds then e names a statically chosen function not an overload set. If overload resolution fails then e names an overload set and the program is ill-formed. That's my understanding at least. So, yes, you can use decltype on an overloaded function and the program is not ill-formed, so long as overload resolution succeeds. I believe that's true of call expressions in any context. Daniel Walker

On 4/8/2010 1:53 PM, Daniel Walker wrote:
On Thu, Apr 8, 2010 at 2:18 PM, Eric Niebler <eric@boostpro.com> wrote:
7.1.6.2/4: "The type denoted by decltype(e) is defined as follows: — if e is ... or if e names a set of overloaded functions, the program is ill-formed;"
<snip>
If overload resolution succeeds then e names a statically chosen function not an overload set. If overload resolution fails then e names an overload set and the program is ill-formed. That's my understanding at least. So, yes, you can use decltype on an overloaded function and the program is not ill-formed, so long as overload resolution succeeds. I believe that's true of call expressions in any context.
Daniel, you're probably right. Thanks for the clarification. I think Steven is right though that if you use an incomplete type in a function call expression (a possibly overloaded function set), then the program is ill-formed if any signature in the function set requires a complete type. This can happen in any context, decltype or not, so I don't think it has bearing on this discussion. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Fri, Apr 9, 2010 at 4:09 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/8/2010 1:53 PM, Daniel Walker wrote:
On Thu, Apr 8, 2010 at 2:18 PM, Eric Niebler <eric@boostpro.com> wrote:
7.1.6.2/4: "The type denoted by decltype(e) is defined as follows: — if e is ... or if e names a set of overloaded functions, the program is ill-formed;"
<snip>
If overload resolution succeeds then e names a statically chosen function not an overload set. If overload resolution fails then e names an overload set and the program is ill-formed. That's my understanding at least. So, yes, you can use decltype on an overloaded function and the program is not ill-formed, so long as overload resolution succeeds. I believe that's true of call expressions in any context.
Daniel, you're probably right. Thanks for the clarification. I think Steven is right though that if you use an incomplete type in a function call expression (a possibly overloaded function set), then the program is ill-formed if any signature in the function set requires a complete type. This can happen in any context, decltype or not, so I don't think it has bearing on this discussion.
Yes, and I like the way you put that, focusing on the requirement of the signature. That clarifies things. The type could be incomplete in the context of the signature, but it must be complete in the context of the call expression. With decltype those context could overlap, which is something new to think about. So, yeah, in general, if some signature requires a type to be complete, then the function can't be used in context where the type is incomplete... But I can think of one counterexample. If SFINAE drops the signature during template substitution, then overload resolution could still succeed. So the following, I believe, is valid even though S is incomplete. g++ accepts it. template<class T> int f(typename T::foo, T x = T()); template<class T> int f(...); struct S; typedef decltype(f<S>(0)) type; Daniel Walker

On 4/9/2010 2:39 PM, Daniel Walker wrote:
So, yeah, in general, if some signature requires a type to be complete, then the function can't be used in context where the type is incomplete... But I can think of one counterexample. If SFINAE drops the signature during template substitution, then overload resolution could still succeed. So the following, I believe, is valid even though S is incomplete. g++ accepts it.
template<class T> int f(typename T::foo, T x = T());
template<class T> int f(...);
struct S; typedef decltype(f<S>(0)) type;
Whoa, that's wacky. I tried comeau in strict C++03 mode, removed the use of decltype from this example, and confirmed that whether the type is complete or not actually changes which overload gets selected. I didn't think type completeness was a SFINAE case. This has ODR written all over it -- I don't know if it's valid code or not. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On 04/09/2010 06:46 PM, Eric Niebler wrote:
On 4/9/2010 2:39 PM, Daniel Walker wrote:
So, yeah, in general, if some signature requires a type to be complete, then the function can't be used in context where the type is incomplete... But I can think of one counterexample. If SFINAE drops the signature during template substitution, then overload resolution could still succeed. So the following, I believe, is valid even though S is incomplete. g++ accepts it.
template<class T> int f(typename T::foo, T x = T());
template<class T> int f(...);
struct S; typedef decltype(f<S>(0)) type;
Whoa, that's wacky. I tried comeau in strict C++03 mode, removed the use of decltype from this example, and confirmed that whether the type is complete or not actually changes which overload gets selected. I didn't think type completeness was a SFINAE case. This has ODR written all over it -- I don't know if it's valid code or not.
While not strictly the same, this sounds like the following would apply, too: 14.7.1/6: "If an implicit instantiation of a class template specialization is required and the template is declared but not defined, the program is ill-formed." (Again, I understand that's not exactly the case here, but the spirit is the same.) Stefan -- ...ich hab' noch einen Koffer in Berlin...

Eric Niebler <eric@boostpro.com> writes:
On 4/6/2010 12:28 PM, Christophe Henry wrote:
I start having a bit of experience with decltype and VC compilers (sigh) through my eUML front-end for MSM and I can give you one reason: because it's probably not just VC10. I have here and there this problem (and others) with VC9 too. It might just happen in different conditions.
This is NOT the same issue. VC9 does not have the decltype keyword. We're not talking about typeof emulation. Please don't take us off-topic.
The issue is whether the decltype keyword is too broken on VC10 to define BOOST_NO_DECLTYPE. I think it /may/ be, so we should define it just to be safe, at least for 1.43.
I agree. There's more than one bug in VC10's implementation of decltype. The following directly impacts result_of: https://connect.microsoft.com/VisualStudio/feedback/details/541365/decltype-... Note the comment by Jon Caves that this won't be fixed in the VC10 release. Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++0x thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

On Tue, Apr 6, 2010 at 3:49 PM, Eric Niebler <eric@boostpro.com> wrote:
...
The issue is whether the decltype keyword is too broken on VC10 to define BOOST_NO_DECLTYPE. I think it /may/ be, so we should define it just to be safe, at least for 1.43.
Eric, where do we stand on this? Does the VC10 decltype problem in the beta still exist in the final release of VC10? --Beman

On 4/19/2010 5:45 AM, Beman Dawes wrote:
On Tue, Apr 6, 2010 at 3:49 PM, Eric Niebler <eric@boostpro.com> wrote:
...
The issue is whether the decltype keyword is too broken on VC10 to define BOOST_NO_DECLTYPE. I think it /may/ be, so we should define it just to be safe, at least for 1.43.
Eric, where do we stand on this? Does the VC10 decltype problem in the beta still exist in the final release of VC10?
The bug is not in VC10 per se, but in the specification of decltype. An issue has been raised with the standardization committee and proposed wording has been suggested. Hopefully, it'll make it into C++0x Final. What that means for Boost.Config is unclear to me. We may decide to define a defect macro for this particular buggy decltype behavior, since gcc's decltytpe works this way, too. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Mon, Apr 19, 2010 at 6:28 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/19/2010 5:45 AM, Beman Dawes wrote:
On Tue, Apr 6, 2010 at 3:49 PM, Eric Niebler <eric@boostpro.com> wrote:
...
The issue is whether the decltype keyword is too broken on VC10 to define BOOST_NO_DECLTYPE. I think it /may/ be, so we should define it just to be safe, at least for 1.43.
Eric, where do we stand on this? Does the VC10 decltype problem in the beta still exist in the final release of VC10?
The bug is not in VC10 per se, but in the specification of decltype. An issue has been raised with the standardization committee and proposed wording has been suggested. Hopefully, it'll make it into C++0x Final.
What that means for Boost.Config is unclear to me. We may decide to define a defect macro for this particular buggy decltype behavior, since gcc's decltytpe works this way, too.
That sounds like a reasonable approach. Care to propose a name? What is the CWG issue number? --Beman

The issue is whether the decltype keyword is too broken on VC10 to define BOOST_NO_DECLTYPE. I think it /may/ be, so we should define it just to be safe, at least for 1.43.
Eric, where do we stand on this? Does the VC10 decltype problem in the beta still exist in the final release of VC10?
The bug is not in VC10 per se, but in the specification of decltype. An issue has been raised with the standardization committee and proposed wording has been suggested. Hopefully, it'll make it into C++0x Final.
What that means for Boost.Config is unclear to me. We may decide to define a defect macro for this particular buggy decltype behavior, since gcc's decltytpe works this way, too.
That sounds like a reasonable approach. Care to propose a name? What is the CWG issue number?
If all compilers decltype implementations have this issue, *and* it is currently std conforming, then maybe we shouldn't have a defect macro at all? Or at least wait until we know whether this is likely to be fixed in the std? Just my 2c, John.

John Maddock wrote:
Beman Dawes wrote:
Eric Niebler wrote:
What that means for Boost.Config is unclear to me. We may decide to define a defect macro for this particular buggy decltype behavior, since gcc's decltytpe works this way, too.
That sounds like a reasonable approach. Care to propose a name? What is the CWG issue number?
If all compilers decltype implementations have this issue, *and* it is currently std conforming, then maybe we shouldn't have a defect macro at all? Or at least wait until we know whether this is likely to be fixed in the std?
Just my 2c, John.
Oh. Yeah, that sounds better. And it seems to me that VC10's decltype probably works well enough to leave BOOST_NO_DECLTYPE undefined, but I'd see some more examples of code in the wild that would be broken by the bug Anthony is referring to. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Tue, Apr 20, 2010 at 1:44 PM, Eric Niebler <eric@boostpro.com> wrote:
John Maddock wrote:
Beman Dawes wrote:
Eric Niebler wrote:
What that means for Boost.Config is unclear to me. We may decide to define a defect macro for this particular buggy decltype behavior, since gcc's decltytpe works this way, too.
That sounds like a reasonable approach. Care to propose a name? What is the CWG issue number?
If all compilers decltype implementations have this issue, *and* it is currently std conforming, then maybe we shouldn't have a defect macro at all? Or at least wait until we know whether this is likely to be fixed in the std?
Just my 2c, John.
Oh. Yeah, that sounds better. And it seems to me that VC10's decltype probably works well enough to leave BOOST_NO_DECLTYPE undefined, but I'd see some more examples of code in the wild that would be broken by the bug Anthony is referring to.
Also, just to be clear, there are two issues here: 1) Given Eric's earlier example of an incomplete type in decltype, both msvc and gcc fail to halt cleanly in a reasonable amount of time due to either ICE or some other internal problem. So, that appears to be an issue with the compilers. 2) There's the open question as to whether/how the standard should change regarding decltype's behavior in context where the type is incomplete. That's an issue with the standard. So, we know that, regardless of the standard, some compilers don't always behave nicely with incomplete decltypes. And additionally, the current standard specification for incomplete decltypes may change. So, if it were useful, we could start identifying more fine-grained aspects of decltype functionality on various compilers and/or standard drafts; e.g. something like BOOST_NO_DECLTYPE_FOR_COMPLETE_TYPES, BOOST_NO_DECLTYPE_FOR_INCOMPLETE_TYPES. A compiler conforming to the current draft standard only needs decltype for complete types, and both msvc and gcc appear to have that implemented well enough. Daniel Walker

Eric Niebler <eric@boostpro.com> writes:
John Maddock wrote:
Beman Dawes wrote:
Eric Niebler wrote:
What that means for Boost.Config is unclear to me. We may decide to define a defect macro for this particular buggy decltype behavior, since gcc's decltytpe works this way, too.
That sounds like a reasonable approach. Care to propose a name? What is the CWG issue number?
If all compilers decltype implementations have this issue, *and* it is currently std conforming, then maybe we shouldn't have a defect macro at all? Or at least wait until we know whether this is likely to be fixed in the std?
Just my 2c, John.
Oh. Yeah, that sounds better. And it seems to me that VC10's decltype probably works well enough to leave BOOST_NO_DECLTYPE undefined, but I'd see some more examples of code in the wild that would be broken by the bug Anthony is referring to.
I found the bug when trying to use a decltype-based result_of on a function returning a class with a user-defined default constructor. I'll try and find some other examples. Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++0x thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

Beman Dawes <bdawes@acm.org> writes:
On Tue, Apr 6, 2010 at 3:49 PM, Eric Niebler <eric@boostpro.com> wrote:
...
The issue is whether the decltype keyword is too broken on VC10 to define BOOST_NO_DECLTYPE. I think it /may/ be, so we should define it just to be safe, at least for 1.43.
Eric, where do we stand on this? Does the VC10 decltype problem in the beta still exist in the final release of VC10?
decltype is still broken in the final release of VC10. e.g. the following code deduces the return type of getOne() to be one& rather than one, causing an error on the "res r" line. Bizarrely, this problem goes away if NO_CONSTRUCTOR is defined, as the return type is deduced correctly. I am also aware of other scenarios where decltype doesn't work correctly on VC10, but don't have good test cases for them. class one { #ifndef NO_CONSTRUCTOR public: one() {} #endif }; one getOne() { return one(); } template<typename F> void baz(F f) { typedef decltype(f()) res; res r; } int main() { baz(getOne); } Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++0x thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

The issue is whether the decltype keyword is too broken on VC10 to define BOOST_NO_DECLTYPE. I think it /may/ be, so we should define it just to be safe, at least for 1.43.
Eric, where do we stand on this? Does the VC10 decltype problem in the beta still exist in the final release of VC10?
decltype is still broken in the final release of VC10. e.g. the following code deduces the return type of getOne() to be one& rather than one, causing an error on the "res r" line. Bizarrely, this problem goes away if NO_CONSTRUCTOR is defined, as the return type is deduced correctly.
For the present I've added that to the BOOST_NO_DECLTYPE test case in SVN Trunk. Also defined BOOST_NO_DECLTYPE in trunk for VC10, but please do change this if there is consensus that it works "well enough". I've also stopped defining the following macros for VC10 as per ticket https://svn.boost.org/trac/boost/ticket/4110: BOOST_NO_CHAR16_T BOOST_NO_CHAR32_T BOOST_NO_INITIALIZER_LISTS BOOST_NO_NULLPTR If anyone thinks these should still be defined, please provide updated test cases. Cheers, John.

While VC10 supports nullptr (yay!), it doesn't support initializer lists or char16_t/char32_t. We picked up an <initializer_list> header from Dinkumware, but I forgot to remove it when I purged the code conditionally compiled under _HAS_INITIALIZER_LISTS from our sources. Oops. (This header doesn't actually do anything because the Core Language support is nonexistent.) We also picked up "typedef unsigned short char16_t;" and "typedef unsigned int char32_t;" from Dinkumware, but they're obviously fake and used in only one place ("typedef basic_string<char16_t> u16string;" and "typedef basic_string<char32_t> u32string;" in <string>). I should have purged this too, but I didn't realize that it would cause problems. See "C++0x Core Language Features In VC10: The Table" at http://blogs.msdn.com/vcblog/archive/2010/04/06/c-0x-core-language-features-... . Anything that's not in this table isn't supported by VC10. Also, the "Forward declared enums" row should say "No" for VC9 and VC10. Thanks, Stephan T. Lavavej Visual C++ Libraries Developer -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of John Maddock Sent: Tuesday, April 20, 2010 10:31 AM To: boost@lists.boost.org Subject: Re: [boost] [config] vc10 and BOOST_NO_DECLTYPE
The issue is whether the decltype keyword is too broken on VC10 to define BOOST_NO_DECLTYPE. I think it /may/ be, so we should define it just to be safe, at least for 1.43.
Eric, where do we stand on this? Does the VC10 decltype problem in the beta still exist in the final release of VC10?
decltype is still broken in the final release of VC10. e.g. the following code deduces the return type of getOne() to be one& rather than one, causing an error on the "res r" line. Bizarrely, this problem goes away if NO_CONSTRUCTOR is defined, as the return type is deduced correctly.
For the present I've added that to the BOOST_NO_DECLTYPE test case in SVN Trunk. Also defined BOOST_NO_DECLTYPE in trunk for VC10, but please do change this if there is consensus that it works "well enough". I've also stopped defining the following macros for VC10 as per ticket https://svn.boost.org/trac/boost/ticket/4110: BOOST_NO_CHAR16_T BOOST_NO_CHAR32_T BOOST_NO_INITIALIZER_LISTS BOOST_NO_NULLPTR If anyone thinks these should still be defined, please provide updated test cases. Cheers, John. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 20 April 2010 19:06, Stephan T. Lavavej <stl@exchange.microsoft.com> wrote:
We picked up an <initializer_list> header from Dinkumware, but I forgot to remove it when I purged the code conditionally compiled under _HAS_INITIALIZER_LISTS from our sources. Oops. (This header doesn't actually do anything because the Core Language support is nonexistent.)
I think we define BOOST_NO_INITIALIZER_LISTS since there isn't initialiser list support, but don't define BOOST_NO_0X_HDR_INITIALIZER_LIST since there is a header. This is technically correct, but a bit confusing. Daniel

On Wed, Apr 21, 2010 at 4:34 AM, John Maddock <boost.regex@virgin.net> wrote:
While VC10 supports nullptr (yay!), it doesn't support initializer lists or char16_t/char32_t.
Confirmed, I've updated the tests and will commit a fix shortly,
Thanks for work on this! While I don't see any reason to hold up beta 1 for this, I think these VC++ 2010 fixes should go in the final release, so go ahead an merge to release as soon as the trunk tests are stable. --Beman

Confirmed, I've updated the tests and will commit a fix shortly,
Thanks for work on this!
While I don't see any reason to hold up beta 1 for this, I think these VC++ 2010 fixes should go in the final release, so go ahead an merge to release as soon as the trunk tests are stable.
OK, will do, John.

Speaking of the VC10 config, do you have any thoughts about the issue mentioned in https://svn.boost.org/trac/boost/ticket/4112 ? Should VC10 define BOOST_HAS_RVALUE_REFS for the benefit of smart_ptr?

Is this question directed to me? VC10 has RTMed, doesn't define macros for specific libraries, and already reports whether it supports rvalue references. (Inspecting _MSC_VER is the correct way to determine whether rvalue references are supported. During VC10's development, we had the compiler define a couple of macros to indicate support for rvalue references, and specifically rvalue references v2, because our branch structure interferes with inspecting _MSC_VER. Those macros are undocumented and unsupported and may be removed at any time, which is why I'm not mentioning their names.) STL -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Richard Webb Sent: Tuesday, April 20, 2010 11:49 AM To: boost@lists.boost.org Subject: Re: [boost] [config] vc10 and BOOST_NO_DECLTYPE Speaking of the VC10 config, do you have any thoughts about the issue mentioned in https://svn.boost.org/trac/boost/ticket/4112 ? Should VC10 define BOOST_HAS_RVALUE_REFS for the benefit of smart_ptr? _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Speaking of the VC10 config, do you have any thoughts about the issue mentioned in https://svn.boost.org/trac/boost/ticket/4112 ?
Should VC10 define BOOST_HAS_RVALUE_REFS for the benefit of smart_ptr?
Yep: that macro is deprecated in favor of BOOST_NO_RVALUE_REFERENCES, I'll fix suffix.hpp to make sure they're defined in synch with each other. John.

Filed as internal bug number Dev10#891430. Thanks, Stephan T. Lavavej Visual C++ Libraries Developer -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Anthony Williams Sent: Tuesday, April 20, 2010 3:06 AM To: boost@lists.boost.org Subject: Re: [boost] [config] vc10 and BOOST_NO_DECLTYPE Beman Dawes <bdawes@acm.org> writes:
On Tue, Apr 6, 2010 at 3:49 PM, Eric Niebler <eric@boostpro.com> wrote:
...
The issue is whether the decltype keyword is too broken on VC10 to define BOOST_NO_DECLTYPE. I think it /may/ be, so we should define it just to be safe, at least for 1.43.
Eric, where do we stand on this? Does the VC10 decltype problem in the beta still exist in the final release of VC10?
decltype is still broken in the final release of VC10. e.g. the following code deduces the return type of getOne() to be one& rather than one, causing an error on the "res r" line. Bizarrely, this problem goes away if NO_CONSTRUCTOR is defined, as the return type is deduced correctly. I am also aware of other scenarios where decltype doesn't work correctly on VC10, but don't have good test cases for them. class one { #ifndef NO_CONSTRUCTOR public: one() {} #endif }; one getOne() { return one(); } template<typename F> void baz(F f) { typedef decltype(f()) res; res r; } int main() { baz(getOne); } Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++0x thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976 _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (13)
-
Anthony Williams
-
Beman Dawes
-
Christophe Henry
-
Daniel James
-
Daniel Walker
-
Eric Niebler
-
Joel Falcou
-
John Maddock
-
Peter Dimov
-
Richard Webb
-
Stefan Seefeld
-
Stephan T. Lavavej
-
Steven Watanabe