How to assert that a constexpr if else clause never happen?
You have to make the discarded statement dependent of the template parameters
template <class...> constexpr std::false_type always_false{};
if constexpr(condition1){
...
} else if constexpr (condition2) {
....
} else if constexpr (condition3) {
....
} else {
static_assert(always_false<T>);
}
This is so because
[temp.res]/8 - The program is ill-formed, no diagnostic required, if
no valid specialization can be generated for a template or a substatement of a
constexpr if
statement within a template and the template is not instantiated, or ...
constexpr if and static_assert
This is talking about a well-established rule for templates - the same rule that allows compilers to diagnose template<class> void f() { return 1; }
. [temp.res]/8 with the new change bolded:
The program is ill-formed, no diagnostic required, if:
- no valid specialization can be generated for a template or a substatement
of aconstexpr if
statement ([stmt.if]) within a
template and the template is not instantiated, or- [...]
No valid specialization can be generated for a template containing static_assert
whose condition is nondependent and evaluates to false
, so the program is ill-formed NDR.
static_assert
s with a dependent condition that can evaluate to true
for at least one type are not affected.
How to skip uncompilable code through constexpr-if in C++?
As mentioned in the comments, "you have to make the discarded statement dependent of the template parameters" - What you are trying to do is not possible without introducing templates.
For example, this would "work" but its far from a good solution. I added it as answer as the similarity to the question that I marked as a duplicate was disputed.
#include <type_traits>
#include <iostream>
int main() {
struct A { int i = 123; };
struct B { int j = 456; };
B x;
[](auto const & x) {
if constexpr(std::is_same_v<std::remove_cvref_t<decltype(x)>, A>) {
std::cout << "A: " << x.i;
} else if constexpr(std::is_same_v<std::remove_cvref_t<decltype(x)>, B>) {
std::cout << "B: " << x.j;
}
}(x);
}
Stop compilation if `if constexpr` does not match
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
.
C++ force compiler error if template resolution fails
You can add static_assert
as
template<class T> struct dependent_false : std::false_type {};
template <typename T>
const T& get() const {
if constexpr ( std::is_same_v<T, C1> )
return this->c1;
else if constexpr( std::is_same_v<T, C2> )
return this->c2;
else
static_assert(dependent_false<T>::value, "some error message");
}
Related Topics
Writing Your Own Stl Container
Why Are Unnamed Namespaces Used and What Are Their Benefits
How to Sort a Vector of Pairs Based on the Second Element of the Pair
How to Use a Custom Deleter With a Std::Unique_Ptr Member
Are Members of a C++ Struct Initialized to 0 by Default
_File_, _Line_, and _Function_ Usage in C++
Why Can't I Compile an Unordered_Map With a Pair as Key
How Does Generic Lambda Work in C++14
How to Perform a Bitwise Operation on Floating Point Numbers
Remove Elements of a Vector Inside the Loop
C++ Dynamic Shared Library on Linux
Why Can't I Use Float Value as a Template Parameter
Difference Between Iostream and Iostream.H
What's "Wrong" With C++ Wchar_T and Wstrings? What Are Some Alternatives to Wide Characters