mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +02:00
Address bind_handler ambiguous overload error when boost/bind/std_placeholders.hpp is included (#2638)
* Address bind_handler ambiguous overload error when boost/bind/std_placeholders.hpp is included Previously, the implementation of bind_handler made the assumption that the trait boost::is_placeholder would be false for types corresponding to values in the std::placeholders namespace. However, boost/bind commit c85b31e3d200dda2a73cf0027a82c6d8e29066f8, `Support use of standard placeholders with boost::bind`, added a new header, boost/bind/std_placeholders.hpp, which adds specializations to boost::is_placeholder for std::placeholders types. When this header is included before a use of boost::bind_handler, it results in compiler errors like the following, due to an internal helper function having overloads for enable_if<boost::is_placeholder...> and enable_if<std::is_placeholder...>, which were previously assumed to be mutually exclusive, but for which both conditions now are true: ../../../boost/beast/core/detail/bind_handler.hpp:126:18: error: call of overloaded 'extract(std::_Placeholder<1>, boost::beast::detail::tuple<int&&>)' is ambiguous 126 | h(extract(detail::get<S>(std::move(args)), | ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 127 | std::forward<ValsTuple>(vals))...); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This header is included in boost/bind/bind.hpp, and is transitively included by headers in many boost libraries including: algorithm asio atomic graph msm multi_index property_tree ptr_container python signals2 test thread Making it possible that an include from one of these libraries will randomly cause bind_handler to fail to compile. This change addresses the issue by eliminating one of the ambiguous overloads and ensuring that boost/bind/std_placeholders.hpp is included in the bind_handler implementation file, so that the enable_if<boost::is_placeholder...> overload can handle both boost::placeholders and std::placeholders values. It also explicitly adds a boost/bind/std_placeholders.hpp include to the bind_handler unit test to prevent this issue from regressing. * Address boost/bind/std_placeholders.hpp feature guards boost/bind/std_placeholders.hpp has the following feature guards: if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) && !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) If this check fails, it will not detect std::placeholders values as placeholders, making the previous solution fail. This update restores the std::is_placeholder overload and adjusts the SFINAE for the boost::is_placeholder overload so that it triggers only if std::is_placeholder is false, making bind_handler work regardless of whether std_placeholders.hpp's feature guard applies. --------- Co-authored-by: Edward Nolan <enolan@maystreet.com>
This commit is contained in:
@ -20,6 +20,7 @@
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <boost/mp11/integer_sequence.hpp>
|
||||
#include <boost/bind/std_placeholders.hpp>
|
||||
#include <boost/is_placeholder.hpp>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
@ -85,7 +86,9 @@ class bind_wrapper
|
||||
static
|
||||
typename std::enable_if<
|
||||
boost::is_placeholder<typename
|
||||
std::decay<Arg>::type>::value != 0,
|
||||
std::decay<Arg>::type>::value != 0 &&
|
||||
std::is_placeholder<typename
|
||||
std::decay<Arg>::type>::value == 0,
|
||||
tuple_element<boost::is_placeholder<
|
||||
typename std::decay<Arg>::type>::value - 1,
|
||||
Vals>>::type&&
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
#include <boost/bind/placeholders.hpp>
|
||||
#include <boost/bind/std_placeholders.hpp>
|
||||
#include <boost/core/exchange.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
Reference in New Issue
Block a user