다음은 내 C++
프로그램에서 수행중인 작업의 기본 인스턴스입니다. 나는 청취자 목록이 모두 std::function
입니다. 저는 청취자가 어떤 종류의 데이터에 관심이 있는지를 의미하는 개념 DataType
을 가지고 있습니다. 여기의 아이디어는 publish-subscribe 패턴과 같습니다. 특정 종류의 데이터에 관심이있는 메소드는 AddListener
을 사용하여 리스너 목록에 자신을 추가 할 수 있어야합니다. 일부 메서드는 필요할 때마다 & 콜백을받습니다.C++에서 templatised std :: function을 에뮬레이트하는 방법
프로그램이 정상적으로 작동합니다. 다음는
#include <iostream>
#include <functional>
#include <vector>
#include <string>
enum class DataType {
Type_1,
Type_2
// and so on
};
typedef std::function<void(std::pair<DataType, std::string>)> MyListenerType;
//template <typename T>
//typedef std::function<void(T>)> MyListenerType;
// How can I emulate the above so that a method passing any kind of primitive data-type namely "int, bool, float or double" can be added into
// my vector of listners.
std::vector<MyListenerType> my_data_listeners_1;
std::vector<MyListenerType> my_data_listeners_2;
void ListenerMethod_Instance_1(std::pair<DataType, std::string> information) {
DataType data_type = information.first;
std::string message = information.second;
std::cout << "ListenerMethod_Instance_1 called with message " << message << "\n";
}
void ListenerMethod_Instance_2(std::pair<DataType, std::string> information) {
DataType data_type = information.first;
std::string message = information.second;
std::cout << "ListenerMethod_Instance_2 called with message " << message << "\n";
}
void AddListener (MyListenerType listener, DataType type_of_interest) {
if (DataType::Type_1 == type_of_interest) {
my_data_listeners_1.push_back(listener);
std::cout << "Added a method instance for DataType::Type_1" << "\n";
}
else if (DataType::Type_2 == type_of_interest) {
my_data_listeners_2.push_back(listener);
std::cout << "Added a method instance for DataType::Type_2" << "\n";
}
else {
std::cout << "Listener type not supported" << "\n";
}
}
void CallAllListnersWhohaveSuscribed() {
if (!my_data_listeners_1.empty()) {
std::string send_message_1 = "some message 123";
std::pair <DataType, std::string> info_to_send_1 = std::make_pair (DataType::Type_1, send_message_1);
for(auto const &listener : my_data_listeners_1) {
listener(info_to_send_1);
}
}
if (!my_data_listeners_2.empty()) {
std::string send_message_2 = "some message 456";
std::pair <DataType, std::string> info_to_send_2 = std::make_pair (DataType::Type_2, send_message_2);
for(auto const &listener : my_data_listeners_2) {
listener(info_to_send_2);
}
}
}
int main() {
// Add ListenerMethod_Instance_1 for instance
DataType data_type_1 = DataType::Type_1;
auto listener_instance_1 = std::bind(ListenerMethod_Instance_1, std::placeholders::_1);
AddListener(listener_instance_1, data_type_1);
// Add ListenerMethod_Instance_2 for instance
DataType data_type_2 = DataType::Type_2;
auto listener_instance_2 = std::bind(ListenerMethod_Instance_2, std::placeholders::_1);
AddListener(listener_instance_2, data_type_2);
CallAllListnersWhohaveSuscribed();
return 0;
}
프로그램의 출력 :
./stdFunctionTest
Added a method instance for DataType::Type_1
Added a method instance for DataType::Type_2
ListenerMethod_Instance_1 called with message some message 123
ListenerMethod_Instance_2 called with message some message 456
그러나 여기에 내가 고민 &을 수정하는 방법입니다.주의 할 점은 각 ListenerMethod_Instance_1
& 은 쌍을 구문 분석하여 원하지 않는 정보를 가져와야한다는 것입니다. 모든 C++ 기본 데이터 형식의 메서드를 "int, bool, float 또는 double"로 설정하여 수신기 벡터에 추가 할 수 있습니다. & 콜백을 수신합니다. 예를 들어, 다음의 메소드는 AddListener
에 "add-able"해야합니다.
void ListenerMethod_Instance_3(int integer_data) {
std::cout << "ListenerMethod_Instance_3 called with integer_data " << integer_data << "\n";
}
이 link here은 다소 다소 다를 수 있습니다. 그러나 나는 그것을 여기의 나의 유스 케이스에 맞추기 위해 고심하고있다. 제발 제안 해주세요.
기본적으로 어떻게 std::function
s의 템플릿 기능을 얻을 수 있습니까?
이것은 'boost :: any'에 유용 할 수 있습니다. – cdhowie
부스트에서 옵션을 사용할 수 없습니다. 'std ::'범위에서 사용할 수있는 것이 있습니까? –
@ HAL9000-Kernel C++로 시작하면'std :: any'를 사용할 수 있습니다. – Rakete1111