基于 SFINAE 的 ifdef

SFINAE-based ifdef

知识问答

使用 #ifdef 是安全的,以防我们希望编译器优化部分代码,如下所示。

#ifdef LOG
mtmd();
#endif

因此,如果在编译时没有定义LOG,那么在执行期间将不会有任何开销。

问题

我有兴趣使用 SFINAE 实现相同的机制。代码的简化版本如下所示。

template <bool cond, typename std::enable_if<cond>::type* = nullptr>
inline void log(void (*func)(int, int), int in, int out) {
 (*func)(in, out);
}

template <bool cond, typename std::enable_if<!cond>::type* = nullptr>
inline void log(void (*func)(int, int), int in, int out) {}

我可以用下面的形式来使用。

void mtmd(int x, int y) { /* Do something */}

int main() {
  constexpr cond = true; // or flase
  int x, y;
  log<cond>(&mtmd, x, y);
}

问题是,当 condfalse 时,会不会有任何开销,或者编译器会优化一切,因为 log 函数是 inline

通常,人们永远无法确定 inline 是否有效,因为它更多地是编译器的线索,而不是真正的要求(当然,在内联问题上,链​​接问题上)和变量它是非常严格的)。当然,编译器很可能会优化掉对 log 的不必要调用,但这不是标准所要求的。正如cpp reference

中所说

Since this meaning of the keyword inline is non-binding, compilers are free to use inline substitution for any function that's not marked inline, and are free to generate function calls to any function marked inline.

为了确保您必须使用 __forceinline 编译器扩展