xeus-cling icon indicating copy to clipboard operation
xeus-cling copied to clipboard

C++17 kernel not working for folding expressions

Open mmoelle1 opened this issue 2 years ago • 1 comments

I tried several version of xeus-cling (including 0.9 which is reported to work with C++17) on the following code (taken from https://quuxplusone.github.io/blog/2020/10/12/fold-a-function/):

#define FWD(x) static_cast<decltype(x)>(x)
#define MOVE(x) static_cast<decltype(x)&&>(x)

template<class F, class TRR>
struct Folder {
    const F& foo_;
    TRR value_;

    template<class U>
    constexpr auto operator+(Folder<F, U>&& rhs) && -> decltype(auto) {
        using R = decltype(foo_(FWD(value_), FWD(rhs.value_)));
        return Folder<F, R>{foo_, foo_(FWD(value_), FWD(rhs.value_))};
    }
};

template<class F>
constexpr auto left_fold(F foo) {
    return [foo = MOVE(foo)](auto&&... args) -> decltype(auto) {
        return (... + Folder<F, decltype(args)>{foo, FWD(args)}).value_;
    };
}

template<class F>
constexpr auto right_fold(F foo) {
    return [foo = MOVE(foo)](auto&&... args) -> decltype(auto) {
        return (Folder<F, decltype(args)>{foo, FWD(args)} + ...).value_;
    };
}

Xeus-cling terminates with the following error message

input_line_7:16:65: error: expected ';' after return statement
        return (... + Folder<F, decltype(args)>{foo, FWD(args)}).value_;
                                                                ^
                                                                ;
Interpreter Error: 

Changing the above code to

template<class F>
constexpr auto left_fold(F foo) {
    return [foo = MOVE(foo)](auto&&... args) -> decltype(auto) {
        auto t = (... + Folder<F, decltype(args)>{foo, FWD(args)});
        return t.value_;
    };
}

seems to work. It seems to be a bug in the interpreter. Or isn't the original version valid C++ code?

Best regards, Matthias

mmoelle1 avatar Apr 13 '22 19:04 mmoelle1

This seems fixed already? It works for me now.

Anyway, I reproduced the problem on an older version. It seems a parser issue, and there is an easy workaround: just change return (... + Folder<F, decltype(args)>{foo, FWD(args)}).value_; to return ((... + Folder<F, decltype(args)>{foo, FWD(args)})).value_;.

adah1972 avatar Jul 28 '23 12:07 adah1972