'Если ветвь 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 прав, не компилируя это.