【问题标题】:‘boost::placeholders’ has not been declared : boost::placeholders::_1'boost::placeholders' 尚未声明:boost::placeholders::_1
【发布时间】:2021-09-25 13:23:26
【问题描述】:

我正在尝试启动一个 ROS 项目,但收到一个非常奇怪的错误:‘boost::placeholders’ has not been declared

我有以下设置:

  1. Ubuntu 20.04

  2. ROSNoetic

  3. Boost 1.71

  4. CMake -> cmake version 3.16.3

下面是我在终端中收到的错误示例:

In file included from /opt/ros/noetic/include/ros/node_handle.h:34,
                 from /opt/ros/noetic/include/ros/ros.h:45,
/opt/ros/noetic/include/ros/publisher.h: In member function ‘boost::function<void(const boost::shared_ptr<ros::SubscriberLink>&)> ros::Publisher::getLastMessageCallback()’:
/opt/ros/noetic/include/ros/publisher.h:179:70: error: ‘boost::placeholders’ has not been declared
  179 |       return boost::bind(&Impl::pushLastMessage, impl_.get(), boost::placeholders::_1);

下面似乎带有这个错误的文件报错:

  template<class M, class T>
  Subscriber subscribe(const std::string& topic, uint32_t queue_size, void(T::*fp)(M), T* obj,
                       const TransportHints& transport_hints = TransportHints())
  {
    SubscribeOptions ops;
    ops.template initByFullCallbackType<M>(topic, queue_size, boost::bind(fp, obj, boost::placeholders::_1));
    ops.transport_hints = transport_hints;
    return subscribe(ops);
  }

this source 之后,我可以确认我添加了C++14

cmake_minimum_required(VERSION 2.8.3)
project(lidar_boat_detection)
set(CMAKE_BUILD_TYPE Debug)
add_compile_options(-std=c++14 -g)

find_package(PCL 1.8 REQUIRED)

include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

find_package(Boost REQUIRED COMPONENTS 
  system
  filesystem 
  date_time 
  thread
 )


find_package(catkin REQUIRED COMPONENTS 
  roscpp
  pcl_conversions
  pcl_ros
  std_msgs
  message_generation
)

我还咨询了this source,并根据新指令添加了#include &lt;boost/bind/bind.hpp&gt;,而不是#include &lt;boost/bind.hpp&gt;,并添加了using namespace boost::placeholders;。然而,这些解决方案都不起作用,我尝试的另一件事是添加 #include &lt;boost/bind/placeholders.hpp&gt;,但这也不起作用:

#ifndef ROSCPP_PUBLISHER_HANDLE_H
#define ROSCPP_PUBLISHER_HANDLE_H

#include "ros/forwards.h"
#include "ros/common.h"
#include "ros/message.h"
#include "ros/serialization.h"

//#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>

#include <boost/thread/mutex.hpp>

using namespace boost::placeholders;

namespace ros
{

  class NodeHandleBackingCollection;

  ....

}

总是从same post 我尝试在文件开头添加以下行#define BOOST_BIND_NO_PLACEHOLDERS,但这也没有用:

#ifndef ROSCPP_PUBLISHER_HANDLE_H
#define ROSCPP_PUBLISHER_HANDLE_H

#define BOOST_BIND_NO_PLACEHOLDERS


#include "ros/forwards.h"
#include "ros/common.h"
#include "ros/message.h"
#include "ros/serialization.h"

//#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>

#include <boost/thread/mutex.hpp>

using namespace boost::placeholders;

namespace ros
{

  class NodeHandleBackingCollection;

  ....

}

我挖了更多,遇到了this post,但不幸的是并没有解决问题。

This question 会很有用,因为这与我遇到的问题非常接近。

编辑

Creating Package: template_package_msgs
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
CMake Error at /usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake:117 (find_package):
  Could not find a package configuration file provided by "boost_bind"
  (requested version 1.71.0) with any of the following names:

    boost_bindConfig.cmake
    boost_bind-config.cmake

  Add the installation prefix of "boost_bind" to CMAKE_PREFIX_PATH or set
  "boost_bind_DIR" to a directory containing one of the above files.  If
  "boost_bind" provides a separate development package or SDK, be sure it has
  been installed.
Call Stack (most recent call first):
  /usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake:182 (boost_find_component)
  /usr/share/cmake-3.16/Modules/FindBoost.cmake:443 (find_package)
  template_package/template_package_msgs/CMakeLists.txt:9 (find_package)


-- Configuring incomplete, errors occurred!
See also "/home/emanuele/sonar_ws/build/CMakeFiles/CMakeOutput.log".
See also "/home/emanuele/sonar_ws/build/CMakeFiles/CMakeError.log"

我对如何解决它的想法已经不多了。感谢您指出解决此问题的正确方向。

【问题讨论】:

  • 我不认为对 ROS 库代码进行更改是一个好主意,但您能否将代码恢复为初始形式,然后 boost::placeholders::_1 替换为_1。您也可以尝试再次恢复您的更改并将 add_definitions(-DBOOST_BIND_NO_PLACEHOLDERS) 添加到您的 CMakeLists.txt 文件,而不是将其添加到 ROS 标头本身。这样,您可以确保在包含任何其他 Boost 标头之前绝对尊重它。
  • #include &lt;boost/bind.hpp 对于 Boost 1.71 应该是正确的。它处理预处理器定义,例如BOOST_BIND_NO_PLACEHOLDERS。您可以通过打开usr/include/boost 来检查是否是这种情况,并检查bind.hpp 是否存在以及文件的内容是什么。
  • 我 101% 同意您不修改 ROS 库代码!但是我是最后的手段,因为我尝试了所有我可能认为没问题的方法。例如,昨天我卸载/重新安装了 ROS 三次,卸载了 boost 的每个实例,今天我只重新安装了 ROS Noetic(因为它带有正确版本的 boost 1.71)我用 @987654356 检查了这个@ 安装后立即Noetic;仔细检查我也做了ldconfig -p | grep libboost)
  • 为了确保我在安装 Noetic 之前删除了 boost 的任何实例,我什至做了 sudo apt autopurge $(dpkg -l | grep boost | grep 1.71 | awk '{print $2}')。最后,我尝试了您对add_definitions(-DBOOST_BIND_NO_PLACEHOLDERS) 的所有正确CMakeLists.txt 文件的建议,但没有任何改变。
  • 我去检查了usr/include/boost,可以确认bind.hpp 在那里。对我来说最后要尝试的是艰难的方法:将boost::placeholders::_1 替换为_1。我不太喜欢这样做,因为修改 ROS 库代码并不好。但我真的不知道出了什么问题......

标签: c++ boost cmake ros


【解决方案1】:

我无法在我的系统上复制您的确切问题。如果我从您的 Bitbucket 克隆您的最小示例,但在 CMakeLists.txt 中保留 add_definitions(-DBOOST_BIND_NO_PLACEHOLDERS) 行,那么它会给我同样的错误,但如果我 remove 它我没有这些问题,它编译得很好。如果即使您删除了此行,此错误仍然存​​在于您的系统上,那么我能想到的唯一可能的原因是,出于某种晦涩的原因您的工作区中的某些其他包或 ROS 本身添加了此定义使你的包的编译然后失败。我实际上会尝试创建一个新的工作区(或将CATKIN_IGNORE 文件放入工作区中的其他包中,然后将$ catkin clean 放入工作区,然后是$ catkin build),看看它是否仍然出现在您的Bitbucket 代码作为唯一的包中在您的工作区中。如果它编译,请继续添加包,直到您找出其他包中的哪个可能导致它。如果没有,那么解决这个困境的唯一方法就是添加一行

#undef BOOST_BIND_NO_PLACEHOLDERS

到您的两个.cpp 文件talker.cppsubscriber.cpp 的顶部(实际上包括ros/ros.h)。但是,在将其与依赖于BOOST_BIND_NO_PLACEHOLDERS 的代码结合使用时,这可能会导致问题。为了减少它破坏你的代码的机会,不要将它添加到头文件中,因为它可能会泄漏到包括你的头文件在内的代码中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    相关资源
    最近更新 更多