Вопрос о делегате, реализованном в C++
Я нашел код делегата, который реализован в C++, и он скомпилирован под vs2017 и работает правильно.
#include<algorithm> #include<functional> #include<iostream> #include<list> #include<string> using namespace std; #ifdef _DEBUG #define OUTPUT(info) cout<<info <<endl<<endl; #else #define OUTPUT(info) #endif template<class C, typename R, typename ...Args> class delegate_class_mem { public: typedef R(C::*class_func_type)(Args...); delegate_class_mem(class_func_type fun, C* class_ptr) : _fun(fun), _class_ptr(class_ptr) {} R operator()(Args&&...args) { return (_class_ptr->*_fun)(args...); } bool operator==(const delegate_class_mem<C, R, Args...>&other) const { if (_class_ptr == other._class_ptr && _fun == other._fun) return true; return false; } template<typename T> bool operator==(const T&&)const { return false; } private: C* _class_ptr; class_func_type _fun; }; template<typename ...T> class delegate { }; template<typename R, typename ...Args> class delegate<R(Args...)> { public: typedef std::function<R(Args...)> delegate_func; typedef std::list<delegate_func> function_list; typedef R(*func_type)(Args...); typedef delegate<R(Args...)> this_type; delegate() { OUTPUT("function type:" << typeid(R(Args...)).name()) OUTPUT("args count:" << sizeof...(Args)) } ~delegate() { func_list.clear(); } this_type& operator-=(func_type func) { auto itr = std::find_if(func_list.begin(), func_list.end(), [&](delegate_func& f)->bool { auto _fun = f.target<R(*)(Args...)>(); if (_fun && *_fun == func) { return true; } return false; }); if (itr != func_list.end()) func_list.erase(itr); return *this; } template<class C> this_type& operator-=(delegate_class_mem<C, R, Args...>&& class_mem_h) { auto itr = std::find_if(func_list.begin(), func_list.end(), [&](delegate_func& f)->bool { auto _fun = f.target<delegate_class_mem<C, R, Args...>>(); if (_fun && *_fun == class_mem_h) { return true; } return false; }); if (itr != func_list.end()) func_list.erase(itr); return *this; } this_type& operator+=(func_type func) { bool exist = false; for (auto it = func_list.begin(); it != func_list.end(); it++) { auto _func = (*it).target<R(*)(Args...)>(); if (_func && *_func == func) { exist = true; break; } } if (!exist) func_list.push_back(func); return *this; } template<class C> this_type& operator+=(delegate_class_mem<C, R, Args...>&& class_mem) { func_list.push_back(class_mem); return *this; } void operator()(Args&& ...args) { for (auto it = func_list.begin(); it != func_list.end(); it++) { try { (*it)(args...); } catch (exception ex) { //do something... } } } private: function_list func_list; }; template<typename C, typename R, typename ...Args> auto makeDelegateClassHelper(R(C::*class_func_type)(Args...), C* class_ptr) ->delegate_class_mem<C, R, Args...> { return delegate_class_mem<C, R, Args...>(class_func_type, class_ptr); } void func1(std::string& str) { std::cout << "func1: " << str << endl; } void func2(std::string& str) { std::cout << "func2: " << str << endl; } int main(int argc, char *argv[]) { std::string str("This is jacky_zz"); delegate<void(std::string&)> _delegate; printf("func1: %p\n", func1); printf("func2: %p\n", func2); _delegate += func1; _delegate += func1; _delegate += func2; _delegate += func2; _delegate(str); return 0; }
Но я использую G++(версия 7.4+) В MSYS2 или Ubuntu 18.0.4, у меня есть ошибки компиляции.
Что я уже пробовал:
Кто знает problemes есть? Теперь я в замешательстве. Кто может указать мне, как исправить проблемы?
Richard MacCutchan
Какие ошибки?
jackyxinli
$ g++ -Wall -std=делегат c++11 -o delegate.cpp
delegate.cpp: в лямбда-функции:
delegate.cpp:77:26: error: expected primary-expression before '(' token
auto _fun = f.target<R(*)(Args...)>();
^
delegate.cpp:77:28: error: expected primary-expression before ')' token
auto _fun = f.target<R(*)(Args...)>();
^
delegate.cpp:77:34: error: expected primary-expression before '...' token
auto _fun = f.target<R(*)(Args...)>();
^~~
delegate.cpp:77:40: error: expected primary-expression before ')' token
auto _fun = f.target<R(*)(Args...)>();
^
delegate.cpp: в лямбда-функции:
delegate.cpp:97:57: error: expected primary-expression before '>' token
авто _fun = Ф.цель&ЛТ;delegate_class_mem&ЛТ;С, Р, Аргументы...&ГТ;&ГТ;();
^~
делегата.КПП:97:60: ошибка: ожидается первичное-выражение до ')' маркер
авто _fun = Ф.цель&ЛТ;delegate_class_mem&ЛТ;С, Р, Аргументы...&ГТ;&ГТ;();
^
delegate.cpp: в функции-члена 'делегат&ЛТ;Р(Аргументы ...)&ГТ;::this_type&амп; делегировать&ЛТ;Р(Аргументы ...)&ГТ;::оператор+=(делегат&ЛТ;Р(Аргументы ...)&ГТ;::func_type)':
delegate.cpp:117:31: error: expected primary-expression before '(' token
auto _func = (*it).target<R(*)(Args...)>();
^
delegate.cpp:117:33: error: expected primary-expression before ')' token
auto _func = (*it).target<R(*)(Args...)>();
^
delegate.cpp:117:39: error: expected primary-expression before '...' token
auto _func = (*it).target<R(*)(Args...)>();
^~~
delegate.cpp:117:45: error: expected primary-expression before ')' token
auto _func = (*it).target<R(*)(Args...)>();
^
0x01AA
Может быть, это поможет: c++ - компиляция C++11 с g++ - переполнение стека[^]
jackyxinli
Я попробовал командовать как удар:
g++ -Wall -std=делегат c++11 -o delegate.cpp
или
g++ -Wall -std=делегат c++0x -o delegate.cpp
не сработать