使用 header 和其中之一带有模板的 cpp 文件进行编译时未定义的引用

Undefined reference when compiling when using header and cpp file with templates in one of them

我一直在尝试编译我的项目,但在尝试时遇到了一些问题。出现的错误特别是:

[build] /usr/bin/ld: CMakeFiles/robot_control.dir/main.cpp.o:(.data.rel.ro._ZTVN4comm15cameraInterfaceE[_ZTVN4comm15cameraInterfaceE]+0x10): undefined reference to `comm::Interface<cv::Mat>::callbackMsg()'

我的项目现在组织如下:

-${HOME_WORKSPACE}
 |-main.cpp 
 |-src
   |-communication.cpp
   |-communication.hpp

header 文件 (communication.hpp) 是:

#include <opencv2/opencv.hpp>
#include <gazebo/gazebo_client.hh>
#include <gazebo/msgs/msgs.hh>
#include <gazebo/transport/transport.hh>
#include <algorithm>

#ifndef COMM_GUARD
#define COMM_GUARD

namespace comm
{
    struct lidarMsg
    {
        float angle_min, angle_increment, range_min, range_max;
        int nranges, nintensities;
        std::vector<int> ranges;
    };

    template <typename T>
    class Interface
    {
        public:
            Interface() : received{false} {};

            virtual void callbackMsg();

            bool receptionAccomplished()
            {
                return this -> received;
            }
            
            T checkReceived()
            {
                return this -> elementReceived;
            }
        
        protected:
            bool received;
            T elementReceived;

    };

    class cameraInterface : public Interface<cv::Mat>
    {
        public:
            void callbackMsg(ConstImageStampedPtr &msg);
    };

    class lidarInterface : public Interface<lidarMsg>
    {
        public:
            void callbackMsg(ConstLaserScanStampedPtr &msg);
    };
}

#endif

源文件(communication.cpp)是:

#include <opencv2/opencv.hpp>
#include <algorithm>
#include <iostream>
#include "communication.hpp"

#ifndef COMM_CPP_GUARD
#define COMM_CPP_GUARD

namespace comm
{

    void cameraInterface::callbackMsg(ConstImageStampedPtr &msg)
    {
        std::size_t width = msg->image().width();
        std::size_t height = msg->image().height();
        const char *data = msg->image().data().c_str();
        cv::Mat im(int(height), int(width), CV_8UC3, const_cast<char *>(data));
        im = im.clone();
        cv::cvtColor(im, im, cv::COLOR_RGB2BGR);

        this->elementReceived = im;
        received = true;
    }

    void lidarInterface::callbackMsg(ConstLaserScanStampedPtr &msg) {

        this->elementReceived.angle_min = float(msg->scan().angle_min());
        this->elementReceived.angle_increment = float(msg->scan().angle_step());
        this->elementReceived.range_min = float(msg->scan().range_min());
        this->elementReceived.range_max = float(msg->scan().range_max());
        this->elementReceived.nranges = msg->scan().ranges_size();
        this->elementReceived.nintensities = msg->scan().intensities_size();

        for (int i = 0; i < this->elementReceived.nranges; i++)
        {
            if (this->elementReceived.ranges.size() <= i)
            {
                this->elementReceived.ranges.push_back(std::min(float(msg->scan().ranges(i)), this->elementReceived.range_max));
            }
            else
            {
                this->elementReceived.ranges[i] = std::min(float(msg->scan().ranges(i)), this->elementReceived.range_max);
            }
        }
    }
}

#endif

主文件(main.cpp)包含以下内容header:

#include <gazebo/gazebo_client.hh>
#include <gazebo/msgs/msgs.hh>
#include <gazebo/transport/transport.hh>
#include <opencv2/opencv.hpp>
#include <opencv2/calib3d.hpp>
#include <iostream>
#include <stdlib.h>

#include "src/communication.hpp"

我包含了#ifndef /#define /#endif 的部分,因为它是我在其他问题中找到的解决此类问题的方法。我一直在切换 CMakeLists.txt 文件,但仍然没有解决此错误的解决方案。

你不能这样做:

        virtual void callbackMsg();

您必须在 .h 文件中实际提供所有模板方法的实现。