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

3

20

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

Drummer answered 8/11, 2018 at 8:32 Comment(2)
I really think you should file a bug report and see how it goes. Best case scenario: it's fix. Bad case scenario : it's not fixed but you got a reason why. Worst case scenario: nothing happens.Afford
I think it has something to do with backwards compatibility. Back in the days when boost::bind was invented there was no constexpr and/or other technics. So they decided to put placeholders into global space. With the current standard it is possible to have them in an namespace. However, removing from global namespace would break a lot of code -> (ugly) workaround solution: using namespace boost::placeholders;.Barracoon
R
21

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

Remmer answered 20/1, 2021 at 16:4 Comment(0)
B
9

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.

Bifocal answered 29/7, 2019 at 13:50 Comment(0)
H
3

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.

Halmstad answered 17/5, 2022 at 12:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.