1aam2am1 Temat założony przez niniejszego użytkownika |
» 2014-08-21 20:26:17 #include <iostream> #include <functional> #include <vector>
class X { public: void f() { std::cout << 0 << '\n'; } }; class Y { public: void f() { std::cout << 123 << '\n'; } };
template < typename F > void wykonaj( F & x, std::function < void( F * ) > fun ) { fun( & x ); }
std::vector < std::function < void() >> lista; template < typename F > void dodaj( F & x, std::function < void( F ) > fun ) { lista.push_back( fun ); }
int main() { X x; Y y; wykonaj < X >( x, & X::f ); dodaj < Y >( y, & Y::f ); }
||=== Build: Debug in bezcelu (compiler: GNU GCC Compiler) ===| C:\Users\Michał Marszałek\Desktop\bezcelu\main.cpp||In instantiation of 'void dodaj(F&, std::function<void(F)>) [with F = Y]':| C:\Users\Michał Marszałek\Desktop\bezcelu\main.cpp|38|required from here| C:\Users\Michał Marszałek\Desktop\bezcelu\main.cpp|29|error: no matching function for call to 'std::vector<std::function<void()> >::push_back(std::function<void(Y)>&)'| ||=== Build failed: 1 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|
|
|
pekfos |
» 2014-08-21 20:29:56 Typy się nie zgadzają, czego się spodziewałeś? |
|
Monika90 |
» 2014-08-21 20:32:05 Można tak: #include <vector> #include <functional> #include <iostream>
class X { public: void f() { std::cout << "X::f\n"; } };
class Y { public: void f() { std::cout << "Y::f\n"; } };
std::vector < std::function < void() >> akcje;
template < class T > void wykonaj_potem( const T & obj, void( T::* f )() ) { akcje.push_back( std::bind( f, obj ) ); }
int main() { X x; wykonaj_potem( x, & X::f ); Y y; wykonaj_potem( y, & Y::f ); for( auto & f: akcje ) f(); }
to wykona akcje na kopiach obiektów (na oryginałach też się da) |
|
1aam2am1 Temat założony przez niniejszego użytkownika |
» 2014-08-21 20:33:37 Dlatego mówię że nie mogę. Ogólnie chodzi oto że mam MessageBox. Który jest wyświetlany z dwoma klawiszami tak i nie. Gdy kliknę tak ma się wykonać ta funkcja. Problem jest taki że aby to zrobić muszę zapisać funkcję w kontenerze (funkcja nie może stopować programu(jedna pętla główna)). |
|
1aam2am1 Temat założony przez niniejszego użytkownika |
» 2014-08-21 20:37:02 Dzięki Monika90 o tym nie pomyślałem. Czytałem przekazywanie motody do funkcji, ale nie wiedziałem że mogę przekazać przez template class.
Edit. Jak to działa? std::bind |
|
pekfos |
» 2014-08-21 20:54:18 Podstawia argumenty, więc możesz coś wywołać z mniejszą ilością, lub brakiem argumentów, a część będzie przekazana 'niejawnie'. Poczytaj np o takiej funkcji jak std::bind2nd() - aktualnie zdeprecjonowana, kamień łupany w porównaniu do std::bind, ale łatwiej zrozumiesz samą ideę. |
|
Monika90 |
» 2014-08-21 21:06:53 A jak nie lubisz std::bind to możesz użyć wyrażenia lambda, co wygląda tak: template < class T > void wykonaj_potem( T & obj, void( T::* f )() ) { T * ptr = & obj; akcje.push_back([ ptr, f ] {( ptr->* f )(); } ); }
tutaj metoda f zostanie wywołana dla oryginalnego obiektu, więc trzeba zadbać o to by ten obiekt jeszcze istniał. |
|
1aam2am1 Temat założony przez niniejszego użytkownika |
» 2014-08-21 21:58:23 Dziękuję bardzo za odpowiedzi. Temat rozwiązany. Zamykam. |
|
1 « 2 » |