gpt4 book ai didi

c++ - Signals2 connect() 使用模板

转载 作者:太空宇宙 更新时间:2023-11-04 14:02:57 27 4
gpt4 key购买 nike

我正在尝试为发送不同类型的数据所需的一些重复函数创建模板类。但是,我的问题(我认为)确实与 InterfacePublisher::addSubscription() 函数有关,该函数利用 boost::signals2::signal::连接()

看起来 connect 函数正在占用基类的位置,即使派生类覆盖了它们。我确信会有解决方案解决这个问题,但我现在坚持了很长时间。

我在下面粘贴我的代码。这个想法是将字符串从 StringPublisher 传递到 StringSubscriber 而无需通过模板对类名进行硬编码:

#include <string>
#include <iostream>

#include <boost/lambda/lambda.hpp>
#include <boost/signals2/signal.hpp>
#include <boost/signals2/signal_base.hpp>
#include <boost/signals2/slot.hpp>
#include <boost/signals2/slot_base.hpp>

template <class T>
class InterfaceSubscriber
{
public:
InterfaceSubscriber(const std::string& name)
: mName (name) {}

virtual void onData (const std::string& source, T& data)
{
std::cout << "InterfaceSubscriber::onData::BASE SHOULD BE IGNORED\n";
}
protected:
const std::string mName;
};




template <class T>
class InterfacePublisher
{
public:
InterfacePublisher(const std::string& publisherName)
: mPublisherName (publisherName)
{
}

void publish(T& data)
{
mSignalArgs(mPublisherName, data);
}

void addSubscription (InterfaceSubscriber<T>* subsc)
{
// The section where I think problem is. There is where the solution should be
mSignalArgs.connect( std::bind (InterfaceSubscriber<T>::onData , *subsc, std::placeholders::_1, std::placeholders::_2) );
}

protected:
boost::signals2::signal<void (const std::string& publisherName, T& data)> mSignalArgs;
const std::string mPublisherName;
};

class StringSubscriber : public InterfaceSubscriber<std::string>
{
public:
StringSubscriber (const std::string& subscName) : InterfaceSubscriber(subscName) {}
void onData (const std::string& source, std::string& data) override
{
std::cout << mName << ":[" << source << "]Received string of value: " << data << std::endl;
}
};


class StringPublisher : public InterfacePublisher<std::string>
{
public:
StringPublisher (const std::string& name) : InterfacePublisher(name) {}
};


int main()
{
StringSubscriber subscriber1("String_Subscriber_1");
StringSubscriber subscriber2("String_Subscriber_2");
StringPublisher publisher("Publisher_Of_String");
publisher.addSubscription(&subscriber1);
publisher.addSubscription(&subscriber2);
std::string str = "Hello World";

// This should lead to StringSubscriber::onData being called, but instead ends up calling InterfaceSubscriber<T>::onData
publisher.publish(str);

}

最佳答案

StringSubscriberstd::bind 的构建过程中被切片仿函数,结果为 InterfaceSubscriber<T>::onData()在运行时类型为 InterfaceSubscriber<T> 的对象上执行而不是提供给 InterfacePublisher<T>::addSubscription() 的对象的运行时类型.

void addSubscription(InterfaceSubscriber<T>* subsc)
{
mSignalArgs.connect(std::bind(&InterfaceSubscriber<T>::onData,
*subsc, ...);
// ^~~ sliced
}

要解决这个问题,要么直接传递指针,要么传递一个 std::ref对象作为实例。

void addSubscription(InterfaceSubscriber<T>* subsc)
{
mSignalArgs.connect(std::bind(&InterfaceSubscriber<T>::onData,
subsc, ...);
// ^~~ pointer
}

void addSubscription(InterfaceSubscriber<T>* subsc)
{
mSignalArgs.connect(std::bind(&InterfaceSubscriber<T>::onData,
std::ref(*subsc), ...);
// ^~~ reference
}

关于c++ - Signals2 connect() 使用模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18386628/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com