Использование Signals2 connect () с шаблонами

Я пытаюсь создать шаблоны классов для некоторых повторяющихся функций, которые потребуются для отправки данных разных типов. Тем не менее, моя проблема (я думаю) действительно с InterfacePublisher :: addSubscription () функция, которая использует повышение :: signals2 :: сигнал :: подключения ().

Это похоже на соединять Функция принимает местоположение базовых классов, даже если производные классы переопределяют их. Я уверен, что это будет исправлено, но я застрял в нем надолго.

Я вставляю свой код ниже. Идея состоит в том, чтобы передать строку из 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);

}

1

Решение

StringSubscriber нарезается во время строительства std::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
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector