Quando vogliamo usare a static_assert
in a if constexpr
dobbiamo rendere la condizione dipendente da alcuni parametri del template. È interessante notare che gcc e clang non sono d'accordo quando il codice è racchiuso in un lambda.
Il codice seguente viene compilato con gcc, ma clang attiva l'asserzione, anche se if constexpr
non può essere vero.
#include <utility>
template<typename T> constexpr std::false_type False;
template<typename T>
void foo() {
auto f = [](auto x) {
constexpr int val = decltype(x)::value;
if constexpr(val < 0) {
static_assert(False<T>, "AAA");
}
};
f(std::integral_constant<int, 1>{});
}
int main() {
foo<int>();
}
Può essere facilmente risolto sostituendo False<T>
con False<decltype(x)>
.
Quindi la domanda è: quale compilatore è giusto? Suppongo che gcc sia corretto perché la condizione in static_assert
dipende da T
, ma non ne sono sicuro.
static_assert(False<int>, "AAA");
equivale a static_assert(false, "AAA");
all'interno della lambda.
f(std::integral_constant<int, 1>{});
Wandbox non attiva l'asserzione: wandbox.org/permlink/UFYAmYwtt1ptsndr