2

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し、呼び出し用のコードを生成しないようにコードを構成したいので、クラスのどこにでも引数として渡すことができます。

それはできますか?

4

3 に答える 3

0

テンプレート定義は、宣言された場所と同じ場所に配置する必要があります。つまり、ヘッダー ファイルで宣言された場所に LogIt 関数を配置する必要があります。現時点では、テンプレートの宣言とその定義を明示的に分離することはできません。

于 2013-08-02T14:25:35.980 に答える
0

これは、Ch での宣言と Cc での定義しかないため、コンパイラがテンプレートをインスタンス化することになっている時点で、テンプレートが非表示になっているためです。

テンプレート定義をヘッダーに移動するか、Cc でインスタンス化を強制します。そのためには、Cc で LogIt 宣言を提供する必要があります。

于 2013-08-02T14:16:41.147 に答える