2

関数への呼び出しの実行時間を追跡するヘルパー関数で std::bind() またはラムダの結果をラップしたいと思います。任意の数のパラメーター (およびクラス メソッド) で動作し、c++11 と互換性のある一般化されたソリューションが必要です。

私の意図は、ラップされた関数を受け取り、それを boost::signals2::signal に渡すことです。そのため、結果の関数オブジェクトは元の関数とシグネチャが同一である必要があります。

私は基本的に、Wrapper次のように機能する魔法のクラスまたは関数を探しています。

std::function<void(int)> f = [](int x) {
    std::cerr << x << std::endl;
};

boost::signals2::signal<void(int)> x_signal;
x_signal.connect(Wrapper<void(int)>(f));
x_signal(42);

これは、42 を印刷するのにかかった時間を計測します。

ありがとう!

4

3 に答える 3

2

あなたがやりたいことは、可変個引数テンプレートで解決できると思います。

http://www.cplusplus.com/articles/EhvU7k9E/

基本的に、引数リストを外側の std::function から内側に「転送」できます。

編集:

以下に、可変個引数テンプレートの概念を使用した最小限の作業例を追加しました。では、内部ラムダ関数に指定されたパラメータを使用してmain(...)、ラムダ関数が別のオブジェクトにラップされます。std::functionこれは、測定する関数をパラメーターとしてテンプレート化された関数に渡すことによって行われますmeasureTimeWrapper。渡された関数と同じシグネチャを持つ関数を返します (のテンプレート引数でそのラムダのパラメーター リストを適切に定義した場合measureTimeWrapper)。

実行時間が測定される関数は、ここに座って、そのパラメーターで定義されたミリ秒数だけ待機します。それ以外は時間計測には全く関係ありません。これはラッパー関数によって行われます。

この方法では、内部関数の戻り値が失われることに注意してください。値を保持したい場合は、値が返される方法を変更することをお勧めします (おそらく、測定された時間と実際の戻り値を含む構造体として)。

-std=c++11少なくともコードをコンパイルすることを忘れないでください。

#include <iostream>
#include <cstdlib>
#include <functional>
#include <chrono>
#include <thread>


template<typename T, typename... Args>
std::function<double(Args...)> measureTimeWrapper(std::function<T> fncFunctionToMeasure) {
  return [fncFunctionToMeasure](Args... args) -> double {
    auto tsStart = std::chrono::steady_clock::now();
    fncFunctionToMeasure(args...);
    auto tsEnd = std::chrono::steady_clock::now();

    std::chrono::duration<double> durTimeTaken = tsEnd - tsStart;

    return durTimeTaken.count();
  };
}

int main(int argc, char** argv) {
  std::function<double(int)> fncMeasured = measureTimeWrapper<void(int), int>([](int nParameter) {
      std::cout << "Process function running" << std::endl;

      std::chrono::milliseconds tsTime(nParameter); // Milliseconds
      std::this_thread::sleep_for(tsTime);
    });

  std::cout << "Time taken: " << fncMeasured(500) << " sec" << std::endl;

  return EXIT_SUCCESS;
}
于 2016-01-26T05:35:14.377 に答える
1
#include <iostream>
#include <functional>

template<typename Signature>
std::function<Signature>    Wrapper(std::function<Signature> func)
{
  return [func](auto... args)
    {
      std::cout << "function tracked" << std::endl;
      return func(args...);
    };
}

int     lol(const std::string& str)
{
  std::cout << str << std::endl;

  return 42;
}

int     main(void)
{
  auto wrapped = Wrapper<int(const std::string&)>(lol);

  std::cout << wrapped("Hello") << std::endl;
}

"function tracked"パーツを必要な追跡ロジック (タイミング、キャッシュなど) に置き換えます。

これには必要c++14ですが

于 2016-01-26T09:39:24.810 に答える