'Если ветвь constexpr' не сбрасывается внутри лямбды, которая находится внутри функции шаблона
Следующий код:
#include <type_traits>
struct X {
static constexpr void x() {}
};
template <class T1, class T2>
constexpr bool makeFalse() { return false; }
template <class T>
void foo() {
T tmp;
auto f = [](auto type) {
if constexpr (makeFalse<T, decltype(type)>()) {
T::x(); // <- clang does not discard
} else {
// noop
}
};
}
int main() {
foo<int>();
}
не компилируется с Clang, но компилируется с GCC. Я не вижу ничего плохого в этом коде, но я не уверен. Прав ли Кланг, не собирая его?
Ответы
Ответ 1
[stmt.if]/2:
Во время создания экземпляра вмещающего шаблонного объекта, если условие не зависит от значения после его создания, отброшенное подсостояние (если оно есть) не создается.
Поскольку makeFalse<T, decltype(type)>()
зависит от значения после создания экземпляра foo<int>
makeFalse<T, decltype(type)>()
впечатление, что T::x()
следует создавать в соответствии со стандартом, а поскольку T::x
плохо сформированный, когда T
- int
, Clang прав, не компилируя это.