6

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,438
  • 68
  • 55
  • 126
4Bytes
  • 175
  • 1
  • 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,806
  • 3
  • 32
  • 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
  • 161,995
  • 14
  • 331
  • 433
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,742
  • 2
  • 23
  • 26
  • 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
  • 159,632
  • 21
  • 358
  • 434