Quando queremos usar a static_assert
em 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 constexpr
nã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