我有一个 Apache 模块 (.so),其中包含一个我试图与 Apache 本身完全分离的类。最大的挫折来源是调试日志。我希望能够通过模板参数将日志记录功能传递给类。当一切都在同一个翻译单元中时,我可以让概念证明工作正常,但是一旦它们不是因为日志记录函数是“未定义的引用”,它就会失败:
/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
为空(它将用于发布版本)并且不为调用生成任何代码,我会有将它作为参数在课堂上的任何地方传递。
可以做到吗?