# 7 Features of C++17 that will simplify your code

## constexpr if

This is a big one!

The static-if for C++!

The feature allows you to discard branches of an if statement at compile-time based on a constant expression condition.

```
if constexpr(cond)
statement1; // Discarded if cond is false
else
statement2; // Discarded if cond is true
```

For example:

```
template <typename T>
auto get_value(T t) {
if constexpr (std::is_pointer_v<T>)
return *t;
else
return t;
}
```

Regarding more code samples? Hmm... `constexpr if`

can be used to replace several tricks that were already done:

- SFINAE technique to remove not matching function overrides from the overload set
- you might want to look at places with C++14's std::enable_if - that should be easily replaced by
`constexpr if`

. - Tag dispatch

So, in most of the cases, we can now just write a `constexpr if`

statement and that will yield much cleaner code. This is especially important for metaprogramming/template code that is, I think, complex by its nature.

A simple example: Fibonacci:

```
template<int N>
constexpr int fibonacci() {return fibonacci<N-1>() + fibonacci<N-2>(); }
template<>
constexpr int fibonacci<1>() { return 1; }
template<>
constexpr int fibonacci<0>() { return 0; }
```

Now, it can be written almost in a 'normal' (no compile time version):

```
template<int N>
constexpr int fibonacci()
{
if constexpr (N>=2)
return fibonacci<N-1>() + fibonacci<N-2>();
else
return N;
}
```

In C++ Weekly episode 18 Jason Turner makes an example that shows that `constexpr if`

won't do any short circuit logic, so the whole expression must compile:

```
if constexpr (std::is_integral<T>::value &&
std::numeric_limits<T>::min() < 10)
{
}
```

For `T`

that is `std::string`

you'll get a compile error because `numeric_limits`

are not defined for strings.

In the C++Now 2017: Bryce Lelbach “C++17 Features"/16th minute there's a nice example, where `constexpr if`

can be used to define `get<N>`

function - that could work for structured bindings.

```
struct S
{
int n;
std::string s;
float d;
};
template <std::size_t I>
auto& get(S& s)
{
if constexpr (I == 0)
return s.n;
else if constexpr (I == 1)
return s.s;
else if constexpr (I == 2)
return s.d;
}
```

Versus previously you would have needed to write:

```
template <> auto& get<0>(S &s) { return s.n; }
template <> auto& get<1>(S &s) { return s.s; }
template <> auto& get<2>(S &s) { return s.d; }
```

As you can see it's questionable which is the simpler code here. Although in this case, we've used only a simple `struct`

, with some real world examples the final code would be much more complex and thus `constexpr if`

would be cleaner.

More details:

- P0292R2
- Simon Brand: Simplifying templates and #ifdefs with if constexpr
- C++ Weekly Special Edition - Using C++17's constexpr if - YouTube - real examples from Jason and his projects.
- C++17: let’s have a look at the constexpr if – FJ - I've taken the idea of fibonacci example from there.
- C++ 17 vs. C++ 14 — if-constexpr – LoopPerfect – Medium - a lot of interesting examples

MSVC 2017.3, GCC: 7.0, Clang: 3.9.