3

可変引数関数パラメーターを使用するクラスで発生した問題を共有しています。次のコードに示すクラス Thread です。関数パターンを使用するための std::thread のラッパーです。

クラス Thread を新しいクラス Functor に継承する際に、この関数でポリモーフィズムを使用したかったのですが、gcc は以下のエラーを返します。

#include <thread>
#include <iostream>

using namespace std;

template<class... Args>
class Thread
{
public:
    virtual void operator()(Args...) = 0;

    void run(Args... args)
    {
    std::thread t(std::forward< Thread<Args...> >(*this), std::forward<Args>(args)...);
    t.join();
    }
};

template<class... Args>
class Functor : public Thread<Args...>
{
public:
    // generates the errors bellow
    virtual void operator()(Args... /*args*/)
    {
    }

    // doesnot work since the pure virtual function wants another prototype of function.
    // void operator()(int)
    // {
    // }
};

int main()
{
    int a = 12;
    Functor<int> f;
    f.run(ref(a));

    return 0;
}
t-Thread-args2.cpp:1 から:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/tuple: 'struct std::_Head_base のインスタンス化で、false>':
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/tuple:215:12: 'struct std から必要::_Tuple_impl, int>'
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/tuple:507:11: 'class std から必要::tuple, int>'
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/functional:1601:39: 'struct std から必要::_Bind_simple(int)>'
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/thread:133:9: 'std から必要: :thread::thread(_Callable&&, _Args&& ...) [with _Callable = Thread; _Args = {int}]'
t-Thread-args2.cpp:14:83: 'void Thread::run(Args ...) [with Args = {int}]' から必要です
t-Thread-args2.cpp:42:17: ここから必要
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/tuple:166:13: エラー: フィールドを宣言できません'std::_Head_base, false>::_M_head_impl' は抽象型 'Thread' になります
t-Thread-args2.cpp:7:7: 注: 次の仮想関数は「スレッド」内で純粋であるため:
t-Thread-args2.cpp:10:18: 注: void Thread::operator()(Args ...) [with Args = {int}]

純粋仮想関数は派生クラスで適切に定義されているため、エラーを本当に理解していません。ただし、関数 run() を派生クラス (Functor) に移動すると機能します。

前もってありがとう、カナー

4

3 に答える 3

2

問題は:

std::forward< Thread<Args...> >(*this)

Threadサブオブジェクトをコピーしようとします。幸いなことに、これは抽象的であるため、予期しない実行時の動作ではなく、コンパイル エラーが発生します。

代わりに参照ラッパーが必要です。

std::ref(*this)
于 2013-02-21T07:53:03.613 に答える
2

[thread.thread.constr]§3 によると、std::threadコンストラクターの最初の引数の型はF&&であり、要件Fは ですMoveConstructible。あなたの場合、FisThreadであり、 is ではありませんMoveConstructible

つまり、std::threadはファンクターを値で格納する必要があり、ファンクターを として転送していますがThread、これは抽象的です。

于 2013-02-21T07:48:56.697 に答える
1

の使用を含む、このトピックへの参加者から提供された複数のアドバイスを検討std::refし、以前のコードで得た問題を解決する実際のコード バージョンを共有したいと思います。

#include <thread>
#include <iostream>

using namespace std;

template<class... Args>
class Thread
{
public:
    virtual void operator()(Args...) = 0;

    void run(Args... args)
    {
    std::thread t(std::ref(*this), args...);
    t.join();
    }
};

template<class... Args>
class Functor : public Thread<Args...>
{
public:
    void operator()(int)
    {
        while (1)
            {
            cout << "42 "; cout.flush();
            }
    }
};

int main()
{
    int a = 12;
    Functor<int> f;
    f.run(ref(a));

    return 0;
}

再度、感謝します。

于 2013-02-21T09:39:05.317 に答える