'Stop compilation if `if constexpr` does not match
I have a template function that checks the type of a template argument with an if constexpr such as
template <typename T>
bool something(T arg) {
if constexpr (std::is_integral_v<T>) {
return true;
} else {
// What can I write here so that something<double>(0.0) does not compile?
}
return false;
}
How can I make the code fail to compile if none of my if constexprs match?
Solution 1:[1]
The soltuion is to use static_assert.
But we can't simply do static_assert(false, "whatever"); in the else branch, because since the condition doesn't depend on the template parameter, assertion might fire early (when the compiler first sees your function body, even if the else branch is never actually taken).
The condition of static_assert has to somehow depend on T, to delay the assertion check until your template is instantinated.
This is what I've been using:
template <auto A, typename...> auto value = A;
if constexpr (foo)
{
...
}
else if constexpr (bar)
{
...
}
else
{
static_assert(value<false, T>, "Invalid template parameter.");
}
Note that if you only have one if constexpr (rather than an if else if chain), then none of that is needed.
Simply move the condition from if to a static_assert and remove the if.
Solution 2:[2]
Just to add another answer, although the idea is the same.
You can just use this in your else branch:
static_assert(!std::is_same_v<T,T>, "")
Kinda less readable but hey it works :)
Solution 3:[3]
I had the same question.
I'm not an expert, but this worked for me and it doesn't require any extra definitions.
static_assert(! std::is_void<std::void_t<T>>::value , "")
First, std::void_t<T> always returns void type for any T.
Then, std::is_void<T>::value is true if T is void.
So this is a way to get true/false from any type T.
Should work from C++17 onward.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Moshe Rabaev |
| Solution 3 | Pedro InĂ¡cio |
