decltype параметра функции внутри вложенной лямбды не компилируется - PullRequest
0 голосов
/ 09 ноября 2018

Следующий код компилируется с помощью clang 6 и 7 и g ++ 7.2. Однако g ++ 8.2 отклоняет это, жалуясь, что error: ‘predicate’ is not captured.

#include <utility>
#include <iostream>

template<bool b>
constexpr auto bool_c = std::bool_constant<b>{};

template<char...  str>
struct string {
};

template<typename T>
constexpr bool is_bool_constant_like_v = (std::is_base_of_v<std::bool_constant<true>, T> ||
                                          std::is_base_of_v<std::bool_constant<false>, T>);

constexpr auto index_if = [](auto predicate, auto &&tup) {
    using predicate_t = decltype(predicate);
    constexpr auto func = [](auto x) {
        using predicate_return_t = decltype(predicate(std::declval<decltype(x)>()));
        if constexpr (is_bool_constant_like_v<predicate_return_t>) {
            return bool_c<predicate_return_t::value>;
        }
    };
    // actual code here callinf func....
    return 42;
};

int main() {
#ifdef __GLIBCPP__
    std::printf("GLIBCPP: %d\n",__GLIBCPP__);
#endif
#ifdef __GLIBCXX__
    std::printf("GLIBCXX: %d %d\n", _GLIBCXX_RELEASE, __GLIBCXX__);
#endif
    //return 0;
    constexpr auto abababa = string<'a', 'b', 'a', 'b', 'a'>{};
    constexpr auto xxx = index_if([](auto x) constexpr { return bool_c<true>; }, abababa);
}

Проблема, похоже, заключается в использовании predicate внутри decltype() в L 18. Я думаю, это ошибка в g ++, или другие компиляторы ошибочны?

Интересно, что если я добавлю захват по умолчанию = во вложенную лямбду, он снова не сможет скомпилироваться в g ++ - 8.2, но теперь жалуется, что predicate is not a constant expression.

Очевидный обходной путь с использованием decltype(std::declval<predicate_t>(....) работает. Так что я просто хотел знать, какой компилятор работает правильно?

Живой пример здесь

...