[reference_wrapper] Overloading operator() in reference_wrapper
Hi all,
std::reference_wrapper includes an overload of operator()[1] which allows a
wrapped function object to be called without needing to first unwrap:
#include
On Tue, Apr 9, 2013 at 12:24 AM, Nathan Crookston < nathan.crookston@gmail.com> wrote:
Hi all,
std::reference_wrapper includes an overload of operator()[1] which allows a wrapped function object to be called without needing to first unwrap:
#include
#include <functional> #include <iostream> int main() { auto f = [](int i) { std::cout << i * 2 << std::endl; }; std::ref(f)(5);//change this to boost::ref and it will not compile. }
I think it would be valuable to update boost::ref to match the standard version. On compilers which support variadic templates and rvalue references the code is obvious. Those which support one or neither could still have overloads for some number of arguments.
This would be handy in a few places, notably boost::gil::for_each_pixel[2]. I know that boost::bind + reference wrapper could be used instead (boost::bind(boost::ref(f), 5)). Given that implementing operator() is relatively simple, and that the standard object based on boost::reference_wrapper has it (rather than requiring std::bind), I'd argue that this change is desirable.
Thanks, Nate
[1]
http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/operat... [2]http://comments.gmane.org/gmane.comp.lang.c%2B%2B.isocpp.general/513
+1 - Jeff
Le 09/04/13 09:24, Nathan Crookston a écrit :
Hi all,
std::reference_wrapper includes an overload of operator()[1] which allows a wrapped function object to be called without needing to first unwrap:
I think it would be valuable to update boost::ref to match the standard version. On compilers which support variadic templates and rvalue references the code is obvious. Those which support one or neither could still have overloads for some number of arguments.
+1. Please could you fill a Trac ticket? Vicente
Hi Vicente, Vicente J. Botet Escriba wrote:
Le 09/04/13 09:24, Nathan Crookston a écrit :
Hi all,
std::reference_wrapper includes an overload of operator()[1] which allows a wrapped function object to be called without needing to first unwrap:
I think it would be valuable to update boost::ref to match the standard version. On compilers which support variadic templates and rvalue references the code is obvious. Those which support one or neither could still have overloads for some number of arguments.
+1. Please could you fill a Trac ticket?
Ticket: https://svn.boost.org/trac/boost/ticket/8442 I couldn't find a component that I thought really fit reference_wrapper -- utility doesn't seem right, since it's in the main boost include directory. I intend to submit a patch as time allows. Thanks, Nate
On 2013/04/09 16:24 +0900, Nathan Crookston wrote:
std::reference_wrapper includes an overload of operator()[1] which allows a wrapped function object to be called without needing to first unwrap: (snip) I think it would be valuable to update boost::ref to match the standard version.
Is it OK to require the template argument to be a complete type? The standard version requires complete type for operator() support, which results in sticking on the boost version for some cases. https://groups.google.com/a/isocpp.org/d/msg/std-discussion/_tavlfXkOrc/wIxT... I think it's better to have two; std::reference_wrapper which has operator() but requires complete types, and boost::reference_wrapper which allows incomplete types but doesn't have operator(), and users can choose between them for their purpose. It can be said as a compatibility problem between older versions of boost. If the new behavior (compile error on incomplete types) was reported as a bug, is it reasonable to just reject? I think it is unreasonable because ref() and cref() can be used to make a tuple with reference members where incomplete types might be expected and operator() is completely irrelevant. http://www.boost.org/doc/libs/1_53_0/libs/tuple/doc/tuple_users_guide.html#m... What do you think? -- k_satoda
2013/5/2 Kazutoshi Satoda
On 2013/04/09 16:24 +0900, Nathan Crookston wrote:
std::reference_wrapper includes an overload of operator()[1] which allows a wrapped function object to be called without needing to first unwrap: (snip) I think it would be valuable to update boost::ref to match the standard version.
Is it OK to require the template argument to be a complete type?
The standard version requires complete type for operator() support, which results in sticking on the boost version for some cases.
https://groups.google.com/a/isocpp.org/d/msg/std-discussion/_tavlfXkOrc/wIxT...
I think it's better to have two; std::reference_wrapper which has operator() but requires complete types, and boost::reference_wrapper which allows incomplete types but doesn't have operator(), and users can choose between them for their purpose.
Isn't it possible to provide operator() and allow T to be incomplete as long as operator() isn't used? Regards, Kris
On 2013/05/02 16:08 +0900, Krzysztof Czainski wrote:
2013/5/2 Kazutoshi Satoda
On 2013/04/09 16:24 +0900, Nathan Crookston wrote: (snip)
I think it would be valuable to update boost::ref to match the standard version.
Is it OK to require the template argument to be a complete type?
The standard version requires complete type for operator() support, which results in sticking on the boost version for some cases.
https://groups.google.com/a/isocpp.org/d/msg/std-discussion/_tavlfXkOrc/wIxT... (snip) Isn't it possible to provide operator() and allow T to be incomplete as long as operator() isn't used?
I think it is possible, provided that the proposed update can omit some parts of the standard version. The standard version has 4 member typedef which are conditionally defined: result_type, argument_type, first_argument_type, second_argument_type. If "to update boost::ref to match the standard version" includes addition of these members, it requires the argument type complete to determine the condition to (or not to) define these typedef. If you decide not to define these typedef based on the incompleteness, it will likely cause ODR violation. If these typedef are omitted, the resulting reference_wrapper can't be used with the standard function adapters etc. The standard 20.8 [function.objects] p5 says:
To enable adaptors and other components to manipulate function objects that take one or two arguments it is required that the function objects correspondingly provide typedefs ...
It sounds hard to accept. -- k_satoda
Kazutoshi Satoda wrote:
The standard version has 4 member typedef which are conditionally defined: result_type, argument_type, first_argument_type, second_argument_type. If "to update boost::ref to match the standard version" includes addition of these members, it requires the argument type complete to determine the condition to (or not to) define these typedef. If you decide not to define these typedef based on the incompleteness, it will likely cause ODR violation.
Interesting. I've always considered these typedefs redundant, but this is the first time I see them as actively harmful.
Hi all, Peter Dimov wrote:
Kazutoshi Satoda wrote:
The standard version has 4 member typedef which are conditionally defined: result_type, argument_type, first_argument_type, second_argument_type. If "to update boost::ref to match the standard version" includes addition of these members, it requires the argument type complete to determine the condition to (or not to) define these typedef. If you decide not to define these typedef based on the incompleteness, it will likely cause ODR violation.
Interesting. I've always considered these typedefs redundant, but this is the first time I see them as actively harmful.
Yes, this is good to know. I wondered why the standard bothered to specify that in our new, decltype-enabled world. I'll update the ticket to reference this discussion. Happily, just having an operator() overload shouldn't require completeness. Thanks, Nate
On 2013/05/03 00:10 +0900, Nathan Crookston wrote:
Peter Dimov wrote:
The standard version has 4 member typedef which are conditionally defined: result_type, argument_type, first_argument_type, second_argument_type. ... (snip) Interesting. I've always considered these typedefs redundant, but this is
Kazutoshi Satoda wrote: the first time I see them as actively harmful.
Yes, this is good to know. I wondered why the standard bothered to specify that in our new, decltype-enabled world. ...
I can guess only one reason that the resulting functors are expected to work with some C++03-style function adapters in some old libraries which may have no plan to adapt C++11 features like decltype. About the requirement of these typedefs in 20.8 [function.objects] p5 to enable standard adapters, I found that there is an open issue LWG #2149 which is proposing to drop it. http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2149
While not opposed to striking this paragraph, we will need the additional wording to fix the openning hole before this issue can move forward.
-- k_satoda
participants (6)
-
Jeffrey Lee Hellrung, Jr.
-
Kazutoshi Satoda
-
Krzysztof Czainski
-
Nathan Crookston
-
Peter Dimov
-
Vicente J. Botet Escriba