Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

funkcja szablonowa w wątku.

Ostatnio zmodyfikowano 2020-01-19 17:23
Autor Wiadomość
Xgrod
Temat założony przez niniejszego użytkownika
funkcja szablonowa w wątku.
» 2020-01-19 10:25:05
Pisałem już na ten temat ale odpowiedź nie pommogła.
Napiszę cały kod:
C/C++
void kwer( int e )
{
    cout << e << endl;
}
class Thread
{
public:
    template < typename Function, typename...Args >
    void f_t( Function && func, Args &&...args )
    {
        func( forward < Args >( args )...);
    }
    template < typename Function, typename...Args >
    void create_thread( Function && func, Args &&...args )
    {
        thread d;
        d = std::thread( f_t < Function, Args...>, std::forward < Function >( func ), std::forward < Args >( args )...);
        d.join();
    }
};

int main()
{
    int e = 2;
    Thread s;
    s.create_thread( kwer, e );
    return 0;
}
a tu błędy kompilatora
required from 'struct std::_Bind_simple_helper<void (Thread::*)(void (&)(int), int&), void (&)(int), int&>'|
required by substitution of 'template<class _Callable, class ... _Args> typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type std::__bind_simple(_Callable&&, _Args&& ...) [with _Callable = void (Thread::*)(void (&)(int), int&); _Args = {void (&)(int), int&}]'|
required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Thread::*)(void (&)(int), int&); _Args = {void (&)(int), int&}]'|
required from 'void Thread::create_thread(Function&&, Args&& ...) [with Function = void (&)(int); Args = {int&}]'|
error: static assertion failed: Wrong number of arguments for pointer-to-member|
Główny problem jest tutaj:
d = std::thread( f_t < Function, Args...>, std::forward < Function >( func ), std::forward < Args >( args )...);
Proszę o napisanie kodu aby działał. Ja nie mam pomysłu co jest nie tak.
P-176089
pekfos
» 2020-01-19 15:52:01
Jak zmieniłeś nagle parametry problemu, to nic dziwnego że nie działa. Teraz te funkcje są niestatycznymi metodami, więc musisz przekazać this jako dodatkowy argument. W wersji prostej bez martwienia się o forwarding wyglądałoby to tak:
C/C++
#include <iostream>
#include <thread>
using namespace std;


class A
{
public:
    A() = default;
    A( const A & ) { std::cout << "copy\n"; }
    A( A && ) { std::cout << "move\n"; }
};


void kwer( int e, const A & a )
{
    cout << e << endl;
}

class ThreadSimple
{
public:
    template < typename Function, typename...Args >
    void f_t( Function func, Args...args )
    {
        func( args...);
    }
   
    template < typename Function, typename...Args >
    void create_thread( Function func, Args...args )
    {
        thread d;
        d = std::thread( & ThreadSimple::f_t < Function, Args...>, this, func, args...);
        d.join();
    }
};

int main()
{
    int e = 2;
    ThreadSimple s;
    A a;
    s.create_thread( & kwer, e, std::move( a ) );
    return 0;
}
move
copy
move
2
Żeby wyeliminować kopiowanie, trzeba skomplikować kod:
C/C++
class Thread
{
public:
    template < typename Function, typename...Args >
    void f_t( Function && func, Args &&...args )
    {
        func( std::forward < Args >( args )...);
    }
   
    template < typename Function, typename...Args >
    void create_thread( Function && func, Args &&...args )
    {
        thread d;
        d = std::thread( std::bind( & Thread::f_t < const Function &, const Args &...>, this, std::forward < Function >( func ), std::forward < Args >( args )...) );
        d.join();
    }
};

int main()
{
    int e = 2;
    Thread s;
    A a;
    s.create_thread( & kwer, e, std::move( a ) );
    return 0;
}
move
move
2
W przypadku gdy całość po drodze przechodzi do innego wątku, trzeba skopiować argumenty żeby nie odwoływać się do potencjalnie nieistniejących obiektów. Robi to wewnętrznie std::thread / std::bind. Kopie argumentów będą l-wartościami, dlatego w drugim kodzie parametry szablonów są jako const&.
P-176091
Xgrod
Temat założony przez niniejszego użytkownika
» 2020-01-19 17:23:08
Dziękuję bardzo oraz przepraszam za trudności.
P-176093
« 1 »
  Strona 1 z 1