基于 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);
}
问题是,当 cond
是 false
时,会不会有任何开销,或者编译器会优化一切,因为 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
编译器扩展
知识问答
使用 #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);
}
问题是,当 cond
是 false
时,会不会有任何开销,或者编译器会优化一切,因为 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
编译器扩展