Kiedy chcemy używać static_assertw sposób if constexprmusimy warunek zależny od jakiegoś parametru szablonu. Co ciekawe, gcc i clang nie zgadzają się, gdy kod jest zawarty w lambda.
Poniższy kod kompiluje się z gcc, ale clang wyzwala aser, nawet jeśli if constexprnie może to być prawda.
#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>();
}
Można to łatwo naprawić, zastępując False<T>przez False<decltype(x)>.
Pytanie brzmi: który kompilator ma rację? Zakładam, że gcc jest poprawny, ponieważ warunek w static_assertzależy od T, ale nie jestem pewien.
static_assert(False<int>, "AAA");jest równoważne z static_assert(false, "AAA");wewnątrz lambda.
f(std::integral_constant<int, 1>{});Wandbox, nie wyzwala potwierdzenia: wandbox.org/permlink/UFYAmYwtt1ptsndr