模板类的非静态成员函数的无效使用

问题描述 投票:0回答:1

尝试从模板类分配回调函数时出现以下错误。我正在访问对象上的回调函数和回调赋值函数。我无法创建回调函数

static
,因为它需要访问指向 Buffer 对象的非静态指针。我怎样才能做到这一点?

下面是代码。这可以在 https://www.onlinegdb.com/

上执行
main.cpp: In function ‘int main()’:
main.cpp:62:37: error: invalid use of non-static member function ‘void Class1::Callback() [with T = unsigned char]’
   62 |     pBuffer->SetWrCallback(pClass1->Callback);
      |                            ~~~~~~~~~^~~~~~~~
main.cpp:43:10: note: declared here
   43 |     void Callback()
      |          ^~~~~~~~
#include <iostream>

using namespace std;

using CallbackAfterWrite = void (*)(void);

template<typename T>
class Buffer
{
    public:
    Buffer() {}
    ~Buffer() {}
    
    std::size_t size()
    {
        return 10;
    }
    
    void SetWrCallback(CallbackAfterWrite wrCallback)
    {
        mWrCallback = wrCallback;
    }
    
    private:
    CallbackAfterWrite mWrCallback;
};

template<typename T>
class Class1
{
    public:
    Class1() {}
    ~Class1() {}
    
    void Callback()
    {
        if(0 != mpBuffer->size())
        {
            std::cout<< "Trigger callback" <<endl;
        }
    }
    
    private:
    Buffer<T> *mpBuffer;
};

int main()
{
    cout<<"Hello World"<<endl;
    
    Buffer<uint8_t>* pBuffer = new Buffer<uint8_t>;
    Class1<uint8_t>* pClass1 = new Class1<uint8_t>;
    
    pBuffer->SetWrCallback(pClass1->Callback);

    return 0;
}

如果回调函数是

static 
并且不需要访问非静态私有数据成员,则此方法有效,但不幸的是,我无法摆脱它。

function c++11 templates callback non-static
1个回答
0
投票

试试这个:

#include <iostream>
#include <functional>

using namespace std;

template<typename T>
class Buffer
{
public:
    Buffer() {}
    ~Buffer() {}
    
    std::size_t size()
    {
        return 10;
    }
    
    void SetWrCallback(std::function<void()> wrCallback)
    {
        mWrCallback = wrCallback;
    }
    
private:
    std::function<void()> mWrCallback;
};

template<typename T>
class Class1
{
public:
    Class1(Buffer<T>* pBuffer) : mpBuffer(pBuffer) {}
    ~Class1() {}
    
    void Callback()
    {
        if (0 != mpBuffer->size())
        {
            std::cout << "Trigger callback" << endl;
        }
    }
    
private:
    Buffer<T>* mpBuffer;
};

int main()
{
    cout << "Hello World" << endl;
    
    Buffer<uint8_t>* pBuffer = new Buffer<uint8_t>;
    Class1<uint8_t>* pClass1 = new Class1<uint8_t>(pBuffer);
    
    pBuffer->SetWrCallback([pClass1]() { pClass1->Callback(); });

    return 0;
}

出现您遇到的问题是因为您尝试将非静态成员函数分配为函数指针的回调。非静态成员函数有一个隐式的“this”参数,该参数指向类的实例。然而,函数指针默认不捕获“this”指针。

要解决这个问题,您可以使用 lambda 和 std::function 的组合。 Lambda 可以捕获类的实例,然后您可以将 lambda 包装在 std::function 中,该函数可以分配给回调。

在 Buffer 类中,我将 mWrCallback 的类型更改为 std::function 以保存可调用对象。 在 Class1 构造函数中,我将 Buffer 实例传递给 Class1 构造函数,以便它可以访问缓冲区的实例。 在 main 中设置回调时,我使用 lambda 捕获 pClass1 的实例,然后调用其 Callback 成员函数。 这样,lambda 捕获了必要的上下文,并且 std::function 确保可以正确调用回调。

© www.soinside.com 2019 - 2024. All rights reserved.