Search code examples
c++boost

running make is failing from boost::bind with _1 and _2 placeholders...?


I am trying to run make to build a project, and I am getting:

In file included from validation.cpp:46:
In file included from /opt/homebrew/opt/boost/include/boost/math/distributions/poisson.hpp:40:
In file included from /opt/homebrew/opt/boost/include/boost/math/special_functions/gamma.hpp:17:
In file included from /opt/homebrew/opt/boost/include/boost/math/tools/series.hpp:16:
/opt/homebrew/opt/boost/include/boost/math/tools/config.hpp:23:6: warning: "The minimum language standard to use Boost.Math will be C++14 starting in July 2023 (Boost 1.82 release)" [-W#warnings]
#    warning "The minimum language standard to use Boost.Math will be C++14 starting in July 2023 (Boost 1.82 release)"
     ^
validation.cpp:173:111: error: use of undeclared identifier '_1'
        pool.NotifyEntryRemoved.connect(boost::bind(&MemPoolConflictRemovalTracker::NotifyEntryRemoved, this, _1, _2));
                                                                                                              ^
validation.cpp:173:115: error: use of undeclared identifier '_2'
        pool.NotifyEntryRemoved.connect(boost::bind(&MemPoolConflictRemovalTracker::NotifyEntryRemoved, this, _1, _2));
                                                                                                                  ^
validation.cpp:183:114: error: use of undeclared identifier '_1'
        pool.NotifyEntryRemoved.disconnect(boost::bind(&MemPoolConflictRemovalTracker::NotifyEntryRemoved, this, _1, _2));
                                                                                                                 ^
validation.cpp:183:118: error: use of undeclared identifier '_2'
        pool.NotifyEntryRemoved.disconnect(boost::bind(&MemPoolConflictRemovalTracker::NotifyEntryRemoved, this, _1, _2));
                                                                                                                     ^
1 warning and 4 errors generated.
make[2]: *** [libbitcoin_server_a-validation.o] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all-recursive] Error 1

Why is the compiler complaining about _1 and _2 ?

I read through the troubleshooting docs at: https://www.boost.org/doc/libs/1_64_0/libs/bind/doc/html/bind.html#bind.troubleshooting.msvc_specific_using_boost_bind

But I don't see anything about this problem, nor how to fix it.


Solution

  • Why is the compiler complaining about _1 and _2 ?

    You didn't show your code. However the messages quote these lines:

    pool.NotifyEntryRemoved.connect(boost::bind(&MemPoolConflictRemovalTracker::NotifyEntryRemoved, this, _1, _2));
    pool.NotifyEntryRemoved.disconnect(boost::bind(&MemPoolConflictRemovalTracker::NotifyEntryRemoved, this, _1, _2));
    

    Now, since _1 and _2 are not found, you know it's missing qualification boost::placeholders::_1 or a using-directive like

    using namespace boost::placeholders;
    

    Note that in (very!) old versions of Boost the placeholders would just be in the global namespace. For a long series of releases, including the 1.83.0 upcoming version, still warns about this change if you include the legacy header

    #include <boost/bind.hpp>
    

    instead of the new location:

    #include <boost/bind/bind.hpp>
    

    The warning you'll see is this:

    BOOST_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."
    )
    

    As you can see this gives you yet another remedy, which I will not recommend. Apparently the library that you're using switched their implementation over to the cleaner namespaced version and your code silently depended on the deprecated global placeholders.