我经常这样写类:
Logger::Logger(bool log_time_, bool log_percentage, bool log_size):log_time(log_time_)... //made up example
Logger::Log()
{
string log_line;
if (log_time)
log_line += (get_time());
if (log_percentage)
log_line += (get_percentage());
//...
}
我想知道是否有一种方法可以将使用模板魔术的类转换为在编译时执行“if(something)”部分的代码。
编辑:bool变量的值在编译时是已知的。
6条答案
按热度按时间cwtwac6a1#
前言
本文将介绍两种解决方案,一种使用C 03,另一种使用C11。
如果你想要一个真正的编译时间,这是很难的(也就是说,你需要写很多代码),如果这是保证**没有任何运行时开销,所以以往任何时候(没有函数跳转等)。
不过这是可能的,尽管如果你想添加另一个选项(在C ++03中),代码维护起来会很繁琐。我建议你看看下面的解决方案。
C ++03中的解决方案
您的编译器应该足够聪明,能够优化掉对
LogHelper<+NONE>
的任何调用,不过如果您只是在寻找可读性更强的代码,而不是获得卓越的性能增益,那么这种语法非常好用。...
使用变量模板的解决方案(C++11)
...
zdwk9cvp2#
是的,这是可能的,尽管有些编译器可能不喜欢这样做,但实际上你最终会得到一组不同的类,因为你必须提供布尔值作为模板说明符(可能不是正确的术语)。
我想你最好使用一个虚拟的Log方法,然后创建一些类,每个类定义自己的Log方法。除非你有其他原因,我建议在这种情况下使用虚拟函数而不是模板。
2skhul333#
当然。就像这样:
像
foo<true, false>();
一样调用它。ffdz8vbo4#
为什么要在不需要模板的地方使用模板呢?任何有自尊心的C++编译器都会基于常量表达式进行常量折叠:无论如何,它必须在编译时计算出这些值。也就是说,任何基于常量表达式的条件在运行时都不会存在。这种方法仅有的两个缺点是:
1.您依赖于编译器在相当基本的级别上相当不错
1.从代码中引用的符号从未执行,但仍将被引用
至于布尔标志,你仍然需要确保它们被识别为常量表达式,但是使用模板会强制执行这一点。
7xzttuei5#
你可以做这样的事
foo.Log()
将为no op,bar.log()
将执行您想要的计时器和百分比操作46qrfjad6#
是对于编译时间常量,您可以使用
template
编程:您还可以将中间版本专门化为
Logger<true, false, false>
和Logger<false, true, true>
等。避免多个专门化的另一种方法是将time / percentage / size
分隔为不同的struct
并分别记录它们。