I have a code using “classic” SFINAE.
template<class M> auto power(M const& elem) -> decltype(std::norm(elem)) { return std::norm(elem); }
template<class M, class = std::enable_if_t<(M::rank::value >= 1)>>
auto power(M const& array) {
return accumulate(begin(array), end(array), 0.0, [](auto const& alpha, auto const& omega) { return alpha + power(omega); });
}
This is a recursive (across dimensions or ranks) “power” function that ultimately gives the sum of the squares of the elements by calculating the power of subelements of lower dimension.
Modern C++ incentivizes the use if constexpr
to avoid using SFINAE, like below.
template<class M>
auto power(M const& array) {
if constexpr(M::rank::value >= 1) {
return accumulate(begin(array), end(array), 0.0, [](auto const& alpha, auto const& omega) { return alpha + power(omega); });
} else {
return std::norm(array);
}
}
The problem is that it seems that the expression in the if constexpr
has to be a valid expression in the first place.
Elements don’t have a member type called rank
, so there is a compilation error.
Is there a trick to make the if constexpr
predicate if the expression is invalid?