Wenn wir a static_assert
in a verwenden möchten, if constexpr
müssen wir die Bedingung von einem Vorlagenparameter abhängig machen. Interessanterweise stimmen gcc und clang nicht überein, wenn der Code in ein Lambda eingewickelt ist.
Der folgende Code wird mit gcc kompiliert, aber clang löst die Bestätigung aus, auch wenn das if constexpr
nicht wahr sein kann.
#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>();
}
Es kann leicht durch Ersetzen False<T>
durch behoben werden False<decltype(x)>
.
Die Frage ist also: Welcher Compiler ist richtig? Ich würde annehmen, dass gcc korrekt ist, da die Bedingung in der static_assert
abhängig ist T
, aber ich bin nicht sicher.
static_assert(False<int>, "AAA");
entspricht dem static_assert(false, "AAA");
Inneren des Lambda.
f(std::integral_constant<int, 1>{});
Wandbox lautet, wird die Bestätigung nicht ausgelöst: wandbox.org/permlink/UFYAmYwtt1ptsndr