Apache 自体から完全に分離しようとしているクラスを含む Apache モジュール (.so) があります。フラストレーションの最大の原因は、デバッグ ログです。テンプレート パラメーターを使用して、ログ機能をクラスに渡すことができるようにしたいと考えています。すべてが同じ翻訳単位にある場合、概念実証を正常に機能させることができますが、ログ機能が「未定義の参照」であるため、そうでない場合は失敗します。
/tmp/ccPdPX2A.o: In function `main':
test.cpp:(.text+0x81): undefined reference to `void C::DoThis<&(LogIt(char const*, ...))>()'
collect2: ld returned 1 exit status
これは、Apache がクラスを含むモジュールをロードしようとしたときにも発生します。以下のコードは問題を再現します。
// main.cpp
#include <iostream>
#include "C.h"
void LogIt(const char*, ...)
{
std::cout << "GADZOOKS!\n";
}
int main(int argc, char* argv[])
{
C c;
c.DoThis<LogIt>();
}
// C.h
typedef void (*LogFunction)(const char*, ...);
class C
{
public:
template <LogFunction L>
void DoThis();
template <LogFunction L>
void DoThat();
};
// C.cpp
#include "C.h"
template <LogFunction L>
void C::DoThis()
{
L("DoThis!");
DoThat<L>();
}
template <LogFunction L>
void C::DoThat()
{
L("DoThat!");
}
関数を関数パラメーターとして渡すことに頼る必要はありません。つまり、
template <typename F>
void C::DoThis(F f)
{
f("DoThis!");
}
の本体が空であるかどうか (リリース ビルドの場合) をコンパイラが判断LogIt
し、呼び出し用のコードを生成しないようにコードを構成したいので、クラスのどこにでも引数として渡すことができます。
それはできますか?