[c++0x] result_of

Jonathan Wakely jwakely.gcc@gmail.com
Thu Sep 18 22:37:00 GMT 2008


re libstdc++/37351

I had a go at updating result_of and reference_wrapper to match the
current WP, which raised the following points:

1) Implementations are permitted use special compiler hooks so that
tr1::result_of gives the right answer.
std::result_of must always give the right answer for a well-formed
expression, which can be done with decltype in 0x mode.

2) According to TR1 all function objects defined by the standard
library must give the right answer with tr1::result_of. Making that
work might require a result_type typedef or a result_of partial
specialisation to be added to some components outside the tr1 dir e.g.
std::default_delete (or tr1::result_of could use decltype too.)

3) If the expression is ill-formed, tr1::result_of should still give
an answer in some cases, such as when there is a nested result_type
typedef. N2723 has no such requirement, so I take that to mean
std::result_of should reject ill-formed expressions.

I think the compiler should reject this:

   struct X { };
   typename int (X::*MemFun)();
   result_of< MemFun(X*) >::type i;

because it's not valid to use a pointer-to-member with that syntax
(see n1695 for an interesting proposal to allow it.)

This requirement is easy to implement (just remove tr1::result_of's
special handling for pointer-to-member types) but that breaks
reference_wrapper::operator() and __invoke(), so I made std::result_of
handle pointer-to-member types.  I have asked on the reflector whether
result_of should handle pointers to members.  If it shouldn't, it will
be possible to make result_of reject them, while providing an enhanced
version that does support them and can be used internally.

4) N2723 and TR1 have the same text regarding the arguments types:

"The values ti are lvalues when the corresponding type Ti is a
reference type, and rvalues otherwise."

This might need to be updated with respect to rvalue-references,
otherwise this will compile:

  typedef int (*func)(int&);
  result_of<func(int&&)>::type i = 0;

even though this is not valid:

  int f(int&);
  f( std::move(0) );

I raised this on the lib reflector and suggested the text should be
"The values ti are lvalues when the corresponding type Ti is an
lvalue-reference type" and that is what this patch does, see
_Result_of_util::_S_fwd_arg()

The _S_fwd_* functions in _Result_of_util and _Result_of_impl are
never called, only their return types are needed by the decltype
expressions.

This probably isn't ready to go in, but here's a patch for discussion.
If I've missed an obvious way to do it better please point it out! :-)

Jonathan

WP http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2723.pdf
TR1 http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1836.pdf
n1695 http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1695.html
n1454 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: result_of.20080918.patch
Type: text/x-patch
Size: 12904 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20080918/b5e76c30/attachment.bin>


More information about the Libstdc++ mailing list