2

QtConcurrentのドキュメントから:

QByteArray bytearray = "hello world";
QFuture<QList<QByteArray> > future = QtConcurrent::run(bytearray, &QByteArray::split), ',');
...
QList<QByteArray> result = future.result();

上記のコードスニペットは、std::tr1::bindstd::bind> C ++ 11の場合)と同様の方法で関数をバインドしているように見えます。つまり、非静的メンバー関数(QByteArray::split())を取り、(後で)それがメンバーであるオブジェクトの特定のインスタンス(として提供したbytearray)でそれを呼び出します。

Qtはこれをどのように達成しますか?使用していますか、std::tr1::bindそれともboost::bind舞台裏のどこかですか?

ドキュメントstd::tr1では、または代わりに使用する場合についても言及していますが、そのコンテキストでのバインドさboostれた関数の意味を完全には理解していません。上記の状況は、実際には、他の方法で使用する可能性のある他の状況とは異なる/より専門的/単純ですか?tr1boost

私はソースを通り抜けようとしましたが、すぐに迷子になります!

4

3 に答える 3

2

既存の回答(@Mike Brownと@skyhisiに感謝します)が基礎を築くので、私は自己回答を試みるつもりですが、この特定のケースには対処しません...

ソースから:

QtConcurrent :: run(...)

template <typename T, typename Class>
QFuture<T> run(const Class &object, T (Class::*fn)())
{
  return (new QT_TYPENAME SelectStoredMemberFunctionCall0<T, Class>::type(fn, object))->start();
}

SelectStoredMemberFunctionCall0

template <typename T, typename Class>
struct SelectStoredMemberFunctionCall0
{
  typedef typename SelectSpecialization<T>::template
    Type<StoredMemberFunctionCall0    <T, Class>,
      VoidStoredMemberFunctionCall0<T, Class> >::type type;
};

VoidStoredMemberFunctionCall0

template <typename T, typename Class>
class VoidStoredMemberFunctionCall0 : public RunFunctionTask<T>
{
public:
  VoidStoredMemberFunctionCall0(T (Class::*_fn)() , const Class &_object)
  : fn(_fn), object(_object){ }

  void runFunctor()
  {
    (object.*fn)();
  }
private:
  T (Class::*fn)();
  Class object;
};

上記のことから、Qtは通常の方法でメンバー関数へのポインターを格納していることがわかりますが、他の方法では見過ごされがちなテンプレートにドレスアップすることで、一般性の錯覚が生まれます。

の型とVoidStoredMemberFunctionCall0::object署名VoidStoredMemberFunctionCall0::fnはすべて、に渡される引数で上記で指定されていますQtConcurrent::run

正直なところ、この「暗黙の」テンプレート化が可能であることにさえ気づいていませんでした。誰かがさらに読むことを勧めることができますか?

于 2011-11-16T22:10:19.090 に答える
1

C ++ FAQは、メンバー関数へのポインターを非常によく説明し、落とし穴を説明しています。

ある時点で、次のような行が表示されます。

ret_val = obj_ptr->*func_ptr(param);

ただし、任意のオブジェクトタイプとパラメータタイプを渡すことができるようにテンプレートにラップされ、そこにもスレッドディスパッチが混在します。

于 2011-11-16T19:49:57.360 に答える
0

関数ポインタと、関数が宣言されたクラスのインスタンスを渡しています。これを呼び出すのは、オブジェクトから関数ポインタを逆参照するのと同じくらい簡単です。このStackOverflowの質問は答えを示しています

于 2011-11-16T17:47:21.130 に答える