単純な関数タイマー/プロファイラを作成しようとしています。私の主な目的は、私が素早く、簡単に、控えめに、私がプロファイルしたい任意の関数呼び出しに追加できる関数を作成することです。任意の引数と戻り値を持つ関数のC++「単純な」関数コールバック
のでfoo
、bar
、およびbaz
をプロファイリングする例えば、私は、できるだけ元のコードに影響を与える、次の操作を行うことができますft
(機能タイマー)機能を持つようにしたい:
ft(foo());
ft(bar(1, 2, 3));
int result = ft(baz());
string result = ft(qux("a", 2, 3.4));
注意を、 baz
とqux
の場合は、ft
から返される結果は、関数自身が返す値でなければなりません。
ft
は、私は、任意の引数を持つファンクションのファンクションコールバックを行う方法を言及する複数のスレッドに遭遇して、それでも戻り値を処理する方法に言及することをそう多くなかった
タイミングの全てとのロギングなどを扱い。
これは最も近いもの:Variable number of arguments (va_list) with a function callback?ですが、値を返す関数だけでなく、void関数も処理しようとしています。
マクロの使用がこれを行う方法だと思っていますが、もっと良い方法があるかもしれません。
は、ここで(簡略)私の現在の微弱な試みです:
static Timer fTimer;
class VoidFuncBase
{
public:
virtual void operator()() = 0;
};
class VoidFuncWrapper0 : public VoidFuncBase
{
public:
typedef void (*func)();
VoidFuncWrapper0(func fp) : fp_(fp) { }
void operator()() { fp_(); }
private:
func fp_;
};
template<typename P1>
class VoidFuncWrapper1 : public VoidFuncBase
{
public:
typedef void (*func)(const P1 &);
VoidFuncWrapper1(func fp, const P1 &p1) : fp_(fp), p1_(p1) { }
void operator()() { fp_(p1_); }
private:
func fp_;
P1 p1_;
};
template<typename P1, typename P2>
class VoidFuncWrapper2 : public VoidFuncBase
{
public:
typedef void (*func)(const P1 &, const P2 &);
VoidFuncWrapper2(func fp, const P1 &p1, const P2 &p2)
: fp_(fp), p1_(p1), p2_(p2) { }
void operator()() { fp_(p1_, p2_); }
private:
func fp_;
P1 p1_;
P2 p2_;
};
template<typename R>
class FuncBase
{
public:
virtual R operator()() = 0;
};
template<typename R>
class FuncWrapper0 : public FuncBase<R>
{
public:
typedef R (*func)();
FuncWrapper0(func fp) : fp_(fp) { }
R operator()() { return fp_(); }
private:
func fp_;
};
template<typename R, typename P1>
class FuncWrapper1 : public FuncBase<R>
{
public:
typedef R (*func)(const P1 &);
FuncWrapper1(func fp, const P1 &p1) : fp_(fp), p1_(p1) { }
R operator()() { return fp_(p1_); }
private:
func fp_;
P1 p1_;
};
template<typename R, typename P1, typename P2>
class FuncWrapper2 : public FuncBase<R>
{
public:
typedef R (*func)(const P1 &, const P2 &);
FuncWrapper2(func fp, const P1 &p1, const P2 &p2)
: fp_(fp), p1_(p1), p2_(p2) { }
R operator()() { return fp_(p1_, p2_); }
private:
func fp_;
P1 p1_;
P2 p2_;
};
template<typename R>
R ft(FuncBase<R> func, std::string functionName)
{
unsigned long threadId = getThreadId();
double startTimeMs = fTimer.getMilliseconds();
R result = func();
double duration = fTimer.getMilliseconds() - startTimeMs;
logf("%u %s took %fms", threadId, functionName.c_str(), duration);
return result;
}
void ft(VoidFuncBase func, std::string functionName, int logTimeoutMs)
{
unsigned long threadId = getThreadId();
double startTimeMs = timer.getMilliseconds();
func();
double duration = timer.getMilliseconds() - startTimeMs;
logf("%u %s took %fms", threadId, functionName.c_str(), duration);
}
は現在、私は
を取得しています。しかし、私はおそらく、とにかくこれで間違った方向に向かっています。"error: cannot declare parameter 'func' to be of abstract type 'VoidFuncBase'".
std ::の機能があります。 C++ 03では、すべての種類のテンプレートクラスと関数を作成する必要があるので、首を痛めます。 –
@VJovic:_All kinds_、非型テンプレートパラメータ、式テンプレート、型特性、不思議な繰り返しテンプレートパターン、...、? –
C/C++と呼ばれる言語はありません。 –