Quando queremos usar a static_assertem a if constexpr, devemos tornar a condição dependente de algum parâmetro do modelo. Curiosamente, gcc e clang discordam quando o código é agrupado em uma lambda.
O código a seguir é compilado com o gcc, mas o clang aciona a declaração, mesmo que if constexprnão possa ser verdadeira.
#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>();
}
Pode ser facilmente corrigido substituindo False<T>por False<decltype(x)>.
Então a pergunta é: qual compilador está certo? Eu diria que o gcc está correto porque a condição no static_asserté dependente T, mas não tenho certeza.
static_assert(False<int>, "AAA");é equivalente a static_assert(false, "AAA");dentro do lambda.
f(std::integral_constant<int, 1>{});Wandbox, não aciona a afirmação: wandbox.org/permlink/UFYAmYwtt1ptsndr