Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why boost::bind insists pulling `boost::placeholders` into global namespace?

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>.

like image 413
user2709407 Avatar asked Nov 08 '18 08:11

user2709407


3 Answers

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

like image 83
petke Avatar answered Nov 19 '22 13:11

petke


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.

like image 7
Andreas Haferburg Avatar answered Nov 19 '22 13:11

Andreas Haferburg


Either add:

#define BOOST_BIND_GLOBAL_PLACEHOLDERS

before you import boost headers.

Or just add to your CMakeLists:

add_definitions(-DBOOST_BIND_GLOBAL_PLACEHOLDERS)

when you configure Boost.

like image 2
albisema Avatar answered Nov 19 '22 12:11

albisema