7

How I can compile template function with pre-processor condition? Like that (but it is not working):

template <bool var>
void f()
{
    #if (var == true)
    // ...
    #endif
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
4Bytes
  • 325
  • 3
  • 8

4 Answers4

9

You can't. The preprocessor, as this names indicates, processes the source file before the compiler. It has therefore no knowledge of the values of your template arguments.

slaphappy
  • 6,894
  • 3
  • 34
  • 59
7

You can't do that with the preprocessor. All you can do is delegate the code to a separate template, something like this:

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();
}

Of course, if you need information shared between f() and only_if_true() (which is likely), you have to pass it as parameters. Or make only_if_true a class and store the shared data in it.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
3

If you need to generate different code paths with template parameter, you can just simply use if or other C++ statement:

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

Compiler can optimize it and generate code that doesn't contain such branches.

A little drawback is that some compiler (e.g. Msvc) will generate warnings for conditions which is always constant.

Milo Yip
  • 4,902
  • 2
  • 25
  • 27
  • Unfortunately, this only works if both branches are syntactically and semantically valid. – Angew is no longer proud of SO Nov 14 '12 at 12:06
  • But this way is useful when the code path depending on local variables in `f()`. Using template specialization will be troublesome in this case. – Milo Yip Nov 14 '12 at 12:18
  • @MiloYip, your answer is right, but when I launch program in debug mode all optimizations (except inline functions) not work. – 4Bytes Nov 16 '12 at 17:29
  • Interested readers might like to read the answers to this question asking about these two different approaches ('deterministic `if`' vs SFINAE): http://stackoverflow.com/q/16178756/2757035 – underscore_d Jun 28 '16 at 17:35
1

With C++17's introduction of if constexpr you can discard branches inside a template, much like conditional compilation allows.

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

The code inside the branch has to be syntactically correct, but doesn't have to be well-formed when var is false, because it will be discarded entirely.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458