What to do about std::binary_function and std::unary_function?
std::binary_function and std::unary_function are deprecated, and
scheduled to be removed from the standard in C++17. That means it's
possible that code using these might soon fail to compile when
targeting this standard.
These are still used throughout Boost, including by the libraries
Accumulators, Algorithm, Bimap, Function, Functional, GIL, Graph, ICL,
MPI, Polygon, and Xpressive. You can see all the uses I found in the
1.61 beta boost/ directory at
http://kundor.github.io/ubinary_function_list.html .
All that these classes do are provide the typedefs result_type, and
argument_type (for unary_function) or first_argument_type and
second_argument_type (for binary_function).
In particular, they do not include a virtual operator(), so that one
cannot accept a function object polymorphically as a
std::binary_function&, for example.
So, although it is conceivable that C++98-era user code might check
for inheritance from std::binary_function, it seems rather unlikely:
practically all uses should just depend on the typedefs being present
(which is what the standard library has always done).
With modern C++ standards, the availability of std::result_of,
decltype, and std::function make these typedefs redundant, and
references to them are being phased out of the standard library
(starting with deprecation.)
It seems to me that there are four main possibilities for removing
these classes from Boost. (I'll talk about binary_function in the
following, but it all applies equally to unary_function.)
1) Add some sort of compatibility macro to Boost.Config, to enable
classes to inherit from std::binary_function if it is available, or
add the appropriate typedefs if it is not.
I don't think this is necessary.
2) Remove the inheritance from std::binary_function, and add the typedefs.
This seems to be the default approach: it is used by the C++11
standard itself, and has also already been done by some Boost
libraries, e.g. in container/string.hpp and in
intrusive/priority_compare.hpp.
The drawback here is increased verbosity. Instead of writing
template <class T>
struct functor : std::binary_function
[Nick Matteo]
std::binary_function and std::unary_function are deprecated, and scheduled to be removed from the standard in C++17.
With VS 2015, you can verify that your code isn't using this stuff by defining _HAS_AUTO_PTR_ETC to 0 (ideally on the command line). STL
On 05.05.2016 21:18, Nick Matteo wrote:
3) A modification of approach 2: instead of manually adding the typedefs everywhere, make a base class to provide the typedefs somewhere in Boost. Then replace inheritance from std::binary_function
with inheritance from boost::binary_function .
3a) Provide boost::binary_function
On 6 May 2016 at 03:32, Rainer Deyke
On 05.05.2016 21:18, Nick Matteo wrote:
3) A modification of approach 2: instead of manually adding the typedefs everywhere, make a base class to provide the typedefs somewhere in Boost. Then replace inheritance from std::binary_function
with inheritance from boost::binary_function . 3a) Provide boost::binary_function
, which inherits std::binary_function if it is available, and reimplements std::binary_function otherwise.
I disagree. The standard is getting rid of them for good reason. Boost
should too.
--
Nevin ":-)" Liber
On Fri, May 6, 2016 at 4:32 AM, Rainer Deyke
3a) Provide boost::binary_function
, which inherits std::binary_function if it is available, and reimplements std::binary_function otherwise.
This would need some sort of macro to tell us if std::binary_function is available. I looked into whether any SD-6 feature test macros were being suggested for this. Last year they were considering either __cpp_lib_removed_function_objects or __cpp_lib_removed_deprecated_functionals (https://www.mail-archive.com/features@isocpp.open-std.org/msg00114.html). But ultimately they decided not to provide any macros for this in the current version (23 Feb 2016) at https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendat.... (The relevant row is N4190, listing _none_.) The justification was somehow left out of that page, but can be seen at https://www.mail-archive.com/features%40isocpp.open-std.org/msg00198.html#de... : "These library features are removed because superior alternatives to them were introduced in C++11. Because these alternatives are superior, there is little motivation to maintain code that uses one of these obsolescent features when it is available." So, it seems that Study Group 10 is essentially recommending option 4. -- Nick Matteo
Nick Matteo wrote:
2) Remove the inheritance from std::binary_function, and add the typedefs. 4) Just remove inheritance from std::binary_function (and don't provide typedefs.)
Either one of those would be fine, although I personally would do something in-between and only provide result_type for boost::bind, mostly out of nostalgia. :-)
On Fri, May 6, 2016 at 5:36 PM, Peter Dimov
Either one of those would be fine, although I personally would do something in-between and only provide result_type for boost::bind, mostly out of nostalgia. :-)
Shouldn't boost::bind be updated to use std::result_of instead? (That is, #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL from Boost.Config.) Nick Matteo
participants (5)
-
Nevin Liber
-
Nick Matteo
-
Peter Dimov
-
Rainer Deyke
-
Stephan T. Lavavej