'Если ветвь constexpr' не сбрасывается внутри лямбды, которая находится внутри функции шаблона - PullRequest
27 голосов
/ 29 апреля 2019

следующий код :

#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 Ответ

18 голосов
/ 29 апреля 2019

[stmt.if] / 2

Во время создания экземпляра вмещающей шаблонной сущности, если условие не зависит от значения после его создания, исключаемая подстанция (если есть) не создается.

Поскольку makeFalse<T, decltype(type)>() зависит от значения после создания экземпляра foo<int>, создается впечатление, что экземпляр T::x() должен быть создан в соответствии со стандартом, а поскольку T::x плохо сформирован, когда T is int, Clang прав, не компилируя его.

...