Quando vogliamo usare a static_assertin a if constexprdobbiamo 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 constexprnon 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_assertdipende 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