预处理器和模板参数或代码片段的条件编译

7
我该如何使用预处理器条件编译模板函数?像这样(但它并不起作用):
template <bool var>
void f()
{
    #if (var == true)
    // ...
    #endif
}
4个回答

9

很抱歉,你做不到。预处理器会在编译器之前处理源文件,因此它无法了解您的模板参数的值。


7

你不能通过预处理器来实现这个。你只能将代码委托给一个单独的模板,例如:

template <bool var>
void only_if_true()
{}

template <>
void only_if_true<true>()
{
  your_special_code_here();
}


template <bool var>
void f()
{
  some_code_always_used();
  only_if_true<var>();
  some_code_always_used();
}

当然,如果你需要在 f()only_if_true() 之间共享信息(这很可能),你需要将其作为参数传递。或者将 only_if_true 设为一个类,并将共享数据存储在其中。

3

如果你需要使用模板参数生成不同的代码路径,你可以简单地使用 if 或其他 C++ 语句:

template <bool var>
void f()
{
    if (var == true) {
        // ...
    }
}

编译器可以进行优化并生成不包含这些分支的代码。
小缺点是某些编译器(例如Msvc)会针对始终为常量的条件生成警告。

不幸的是,只有在两个分支都是语法和语义有效的情况下才能正常工作。 - Angew is no longer proud of SO
但是当代码路径依赖于f()中的局部变量时,这种方法非常有用。在这种情况下使用模板特化会很麻烦。 - Milo Yip
@MiloYip,你的答案是正确的,但是当我以调试模式启动程序时,所有优化(除了内联函数)都不起作用。 - 4Bytes
有兴趣的读者可能会想阅读关于这两种不同方法(“确定性if”与SFINAE)的答案,链接如下:https://dev59.com/xWQo5IYBdhLWcg3wR9rE - underscore_d

1
使用C++17引入的if constexpr,您可以像条件编译一样在模板内部丢弃分支。
template <bool var>
void f()
{
    if constexpr (var == true) {
    // ...
    }
}

var为false时,分支内的代码必须在语法上正确,但不必是格式良好的,因为它将被完全丢弃。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接