问题
The following code can be fixed easily, but quite annoying.
#include <functional>
#include <boost/bind.hpp>
void foo() {
using namespace std::placeholders;
std::bind(_1, _2, _3); // ambiguous
}
There's a macro BOOST_BIND_NO_PLACEHOLDERS
, but using this macro will also bring some drawbacks like causing boost::placeholders
disappear from the compile unit included <boost/bind.hpp>
but not included <boost/bind/placeholders.hpp>
.
The name conflicts also comes with other libs like boost::mpl
, I don't think the maintainers don't know the problem, but I want to know why they insist on not deprecating and deleting using namespace boost::placeholders
in <boost/bind.hpp>
.
回答1:
Looks like it has been fixed in newer versions of boost.
When including boost/bind.hpp
we get this message:
#pragma message: The practice of declaring the Bind placeholders (_1, _2, ...) in the global namespace is deprecated. Please use <boost/bind/bind.hpp> + using namespace boost::placeholders, or define BOOST_BIND_GLOBAL_PLACEHOLDERS to retain the current behavior.
The solution is described in https://www.boost.org/doc/libs/1_73_0/boost/bind.hpp
So the "good practice" fix is to instead of
#include <boost/bind.hpp>
which puts the boost::placeholders in global namespace
do
#include <boost/bind/bind.hpp>
which does not put the boost:: placeholders in global namespace.
Then use the qualified names like boost::placeholders::_1
directly, or locally do using namespace boost::placeholders
回答2:
You can use
#define BOOST_BIND_NO_PLACEHOLDERS
before including other Boost headers.
I don't know when this was introduced, only that it works in 1.67. Feel free to edit with more accurate information.
来源:https://stackoverflow.com/questions/53203970/why-boostbind-insists-pulling-boostplaceholders-into-global-namespace