【问题标题】:Call to a templated member function with an object with private members使用具有私有成员的对象调用模板化成员函数
【发布时间】:2021-04-10 22:12:21
【问题描述】:

我有这个模板函数,它的参数是任何对象的成员函数:

// Function that captures the data
template <class T>
bool captureData(T& f_captureObject, bool (T::* f_captureFunction)())
{
    // Lock data access
    std::unique_lock<std::mutex> lock(m_mutex);

    // Capture data and check if it is ready
    if ((f_captureObject.*f_captureFunction)() == true)
    {
        // If data is ready ...

        // Set data flag to ready
        m_isReady = true;

        // Notify if processing thread is waiting
        m_conditionVariable.notify_one();
    }
    else
    {
        // If data is not ready ...

        // Set data flag to not ready
        m_isReady = false;
    }

    // Return grab state
    return !m_isReady;
};

我这样称呼它:

m_monitorLidar.captureData<Lux>(m_lidar, &Lux::captureScanOffline);

其中 m_lidar 是一个 Lux 对象,其 .hpp 为:

#pragma once

// Includes
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// Standard
#include <iostream>
#include <fstream>
#include <thread>

// User
#include "PlatformTypes.hpp"
#include "VariableTypes2.hpp"
#include "Timer.hpp"

// Namespaces
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
using namespace std;
using namespace chrono;

// Class
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
class Lux
{

// Variables
// ------------------------------------------------------------------------------------------------

private:

    // Scan number
    uint32 m_scanNumber;

    // Scan captured
    Scan m_scanCaptured;

    // Scan saved
    Scan m_scanSaved;

    // Flag indicating if scan is captured
    bool m_isCaptured;

    // Flag indicating if scan is saved
    bool m_isSaved;

    // Scans file
    string m_fileScans;

    // Lidar points file stream
    ifstream m_lidarPointsFileStream;

    // Number of scans of a file
    uint32 m_numScansFile;

    // Timer for the simulation
    Timer m_timer;

    // Scan rate for the simulation
    uint64 m_scanRate;

// Functions
// ------------------------------------------------------------------------------------------------

public:
    
    // Constructor
    Lux();

    // Destructor
    ~Lux();

    // Initilization function
    void init();

    // Initilization function in offline mode
    bool initOffline(string f_fileScans);

    // Initilization function in online mode
    bool initOnline();

    // Initilization function in simulation mode
    bool initSimulation(string f_fileScans, uint64 f_scanRate);

    // Capture scan offline
    bool captureScanOffline();

    // Capture scan online
    bool captureScanOnline();

    // Capture scan simulation
    bool captureScanSimulation();

    // Save the captured scan
    void saveScan();

    // Get scan points from sensor/file
    bool getScanPoints();

    // Getters
    uint32 getScanNumber();
    const Scan& getScanCaptured();
    const Scan& getScanSaved();
    bool getIsCaptured();
    bool getIsSaved();

private:

     //Open lidar file
    bool openFile();

    // Close lidar file
    void closeFile();
};

它的.cpp文件是:

#include "Lux.hpp"

Lux::Lux()
{
    init();
}

Lux::~Lux()
{
    // Close lidar file
    closeFile();
}

void Lux::init()
{
    // Error flag
    bool error = false;

    // Scan number
    m_scanNumber = 0U;

    // Init stereo images
    m_scanCaptured.init();

    // Init flag indicating if scan is captured
    m_isCaptured = false;

    // Set flag indicating scan is not saved
    m_isSaved = false;
}

bool Lux::initOffline(string f_fileScans)
{
    // Function error
    bool error = false;

    // Set file path
    m_fileScans = f_fileScans;

    // Open file
    error = openFile();

    // Return error status
    return error;
}

bool Lux::initOnline()
{
    // Function error
    bool error = false;

    // Return error status
    return error;
}

bool Lux::initSimulation(string f_fileScans, uint64 f_scanRate)
{
    // Function error
    bool error = false;

    // Init in offline mode
    error = initOffline(f_fileScans);

    // Set scan rate
    m_scanRate = f_scanRate;

    // Return error status
    return error;
}

bool Lux::captureScanOffline()
{
    // Check if there are scans
    if (m_scanNumber < m_numScansFile)
    {
        // If there are scans ...

        // Read number of echoes
        m_lidarPointsFileStream.read((char*)(m_scanCaptured.ne), p_maxNumberOfPointsPerEcho * sizeof(uint32));

        // Read radial distance
        m_lidarPointsFileStream.read((char*)(m_scanCaptured.sc.rd), p_maxNumberOfPointsPerScan * sizeof(float32));

        // Read x-coordinate
        m_lidarPointsFileStream.read((char*)(m_scanCaptured.cc.x), p_maxNumberOfPointsPerScan * sizeof(float32));

        // Read y-coordinate
        m_lidarPointsFileStream.read((char*)(m_scanCaptured.cc.y), p_maxNumberOfPointsPerScan * sizeof(float32));

        // Read z-coordinate
        m_lidarPointsFileStream.read((char*)(m_scanCaptured.cc.z), p_maxNumberOfPointsPerScan * sizeof(float32));

        // Set is captured flag to true
        m_isCaptured = true;
    }
    else
    {
        // If there are no scans ...

        // Print message
        cout << "No more scans" << endl;

        // Set is captured flag to false
        m_isCaptured = true;
    }

    // Return if there was an error
    return !m_isCaptured;

    return false;
}

bool Lux::captureScanOnline()
{
    return false;
}

bool Lux::captureScanSimulation()
{
    // Function error
    bool error = false;
    // Waiting time to achive the scan rate
    int64 waitTime = 0LL;

    // Start timer
    m_timer.start();

    // Capture scan offline
    error = captureScanOffline();

    // Stop timer
    m_timer.stop();

    // Measure the waiting time
    waitTime = m_scanRate - m_timer.elapsed();

    // If capture was to fast
    if (waitTime > 0LL)
    {
        // Wait a time to achive the scan rate
        this_thread::sleep_for(milliseconds(waitTime));
    }

    // Return error status
    return error;
}

void Lux::saveScan()
{
    // Copy the stereo images
    m_scanSaved = m_scanCaptured;

    // Set flag indicating stereo is saved
    m_isSaved = true;
}

uint32 Lux::getScanNumber()
{
    return m_scanNumber;
}

const Scan& Lux::getScanCaptured()
{
    return m_scanCaptured;
}

const Scan& Lux::getScanSaved()
{
    return m_scanSaved;
}

bool Lux::getIsCaptured()
{
    return m_isCaptured;
}

bool Lux::getIsSaved()
{
    return m_isSaved;
}

// Private functions definition
// --------------------------------------------------------------------------------------------------------------------

bool Lux::openFile()
{
    // Open file
    m_lidarPointsFileStream.open(m_fileScans, ifstream::binary);
    if (!m_lidarPointsFileStream.is_open())
    {
        cout << "Lidar points file could not be opened." << endl;
        return true;
    }

    // Read the number of scans
    m_lidarPointsFileStream.read((char*)(&m_numScansFile), sizeof(uint32));

    return false;
}

void Lux::closeFile()
{
    // Close lidar file
    m_lidarPointsFileStream.close();
}

bool Lux::getScanPoints()
{

}

问题是,Lux 对象必须得到这个错误。对于其他对象,我没有这个错误。

C++ 函数“Lux::Lux(const Lux &)”(隐式声明)不能被引用——它是 删除功能

提前致谢。

【问题讨论】:

  • 如果您显示Lux类定义,它将在几秒钟内得到答复。
  • 模板参数不需要显式指定,应该可以从参数f_captureObject推导出来。不过,我看不到在此函数定义中可能会引用复制构造函数的位置。
  • Partick 提到的内容也很重要。也显示m_monitorLidar 类型的定义。或者全力以赴并发送minimal reproducible example 以阻止我们提出问题
  • 如果你能edit你的问题提供minimal reproducible example会更好。当前的代码 sn-ps 似乎无法说明可能导致您的问题的原因,任何人都可以做的最好的事情就是猜测。
  • 在提供 MRE 时,minimalreproducible 这两个词非常重要!关于最小化,Lux 的大多数(如果不是全部)方法都不需要重现您的错误,大多数字段也不需要(这些都只是问题中的噪音)。您也可以将感冒折叠成一个文件以减少它并使我们更容易。关于再现性,PlatformTypes.hppVariableTypes2.hppTimer.hpp 分别在哪里? ScanTimer 是什么?就目前而言,我们无法获取您问题中的代码并查看您所看到的内容。

标签: c++ templates


【解决方案1】:

我在传递对象时使用 std::ref() 找到了解决方案:

m_monitorLidar.captureData<Lux>(std::ref(m_lidar), &Lux::captureScanOffline);

【讨论】:

  • 为了使答案对将来遇到类似问题的人有用,请通过解释解决问题的原因使答案更有用。这对我来说并不明显,因为 captureData 函数无论如何都接受对第一个参数的引用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-11
  • 2020-03-22
  • 1970-01-01
  • 2016-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多