gpt4 book ai didi

c++日志函数使用模板SFINAE进行条件编译

转载 作者:太空宇宙 更新时间:2023-11-04 11:29:33 25 4
gpt4 key购买 nike

我正在评估是否可以利用 C++11 功能来替换日志记录宏而无需任何运行时额外成本。

我推出了这个演示:

enum class LogLevel {
Fatal = 0,
DFatal = 1,
Error = 2,
Normal = 3,
Verbose = 4,
Debug = 5
};

constexpr LogLevel log_compiled = LogLevel::Normal;
LogLevel log_runtime = LogLevel::Error;

#ifdef NDEBUG
constexpr LogLevel log_fatal = LogLevel::Fatal;
#else
constexpr LogLevel log_fatal = LogLevel::DFatal;
#endif


template <LogLevel L, typename std::enable_if<(L <= log_fatal)>::type* = nullptr>
void Log(std::string message) {

std::cout << "Fatal level: " << (int) L << " Message: " << message << std::endl;
exit(0);
}

template <LogLevel L, typename std::enable_if<(L>log_fatal && L <= log_compiled)>::type* = nullptr>
void Log(std::string message) {

if (L <= log_runtime) {
std::cout << "Level: " << (int) L << " Message: " << message << std::endl;
}

}

template <LogLevel L, typename std::enable_if<(L > log_compiled)>::type* = nullptr>
void Log(std::string message) {
}

int main(int argc, char *argv[]) {

//not compiled
Log<LogLevel::Verbose>("Something to much usual");

//compiled, not printed
Log<LogLevel::Normal>("Something usual");

//compiled, printed
Log<LogLevel::Error>("No disk space");

//compiled, printed, terminate in Debug mode
Log<LogLevel::DFatal>("Unexpected contition, recoverable");

//compiled, printed, terminate always
Log<LogLevel::Fatal>("Unexpected contition, unrecoverable");

return 0;
}

通过这种方式,我以非常一致的方式处理编译时排除、运行时日志级别和致命情况。

它可能适用于带有 << 运算符的流。

我的问题:

//not compiled
Log<LogLevel::Verbose>("Something to much usual");

这实际上会导致大多数编译器出现 NOOP 吗?字符串会存在于代码中吗?

这种方法是个坏主意吗?

最佳答案

正如所写,编译器无法优化

Log<LogLevel::Verbose>("Something to much usual");

因为它构造然后销毁一个 std::string,这可能会产生副作用(例如,使用可能替换的 ::operator new 分配然后释放内存和 ::operator delete)。

但是,如果您编写 Log 模板以采用 const char * 代替,那么可以完全优化调用。给定

template <LogLevel L, typename std::enable_if<(L > log_compiled)>::type* = nullptr>
void Log(const char * ) {
}

int main() {
Log<LogLevel::Verbose>("Something to much usual");
return 0;
}

-O2 处的 g++ 4.9 compiles it简单地

xorl    %eax, %eax
ret

关于c++日志函数使用模板SFINAE进行条件编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25352964/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com