scylladb / seastar

High performance server-side application framework

Home Page:http://seastar.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add `sharded<>::invoke_on_all()` const overload

xemul opened this issue · comments

The map-reduce-s have it, why not have for invoke_on_all()? However, it looks like it's going to break compilation

Consider this

#include <fmt/core.h>

template <typename T>
class wrapper {
    T _x;

public:
    wrapper() : _x() {}

    template <typename Fn>
    requires std::invocable<Fn, T&>
    void call(Fn fn) {
        fmt::print("non-const call\n");
        fn(_x);
    }

    template <typename Fn>
    requires std::invocable<Fn, const T&>
    void call(Fn fn) const {
        fmt::print("const call\n");
        fn(_x);
    }
};

class foo {
public:
    void fn() {
        fmt::print("non-const fn\n");
    }

    void fn() const {
        fmt::print("const fn\n");
    }
};

int main() {
    wrapper<foo> w;

    w.call([] (auto& x) {
        x.fn();
    });
}

Note that there are two wrapper::call() overloads -- const and non-const one, just like we want for sharded::invoke_on_all.
If compiled and run we'll see

non-const call
non-const fn

which is expected -- no const is involved at all. However, if removing the foo::fn() const overload, the whole thing will fail to compile with

x.cc:36:9: error: 'this' argument to member function 'fn' has type 'const foo', but function is not marked const
        x.fn();

Respectively, adding sharded::invoke_on_all() const will fail compilation of any non-const calls to sharded<S>::invoke_on_all(&S::method) for S's that don't have S::method() const-s

i was staring at this for a while. and was checking https://eel.is/c++draft/over.match.funcs . but still cannot figure out a satisfying explanation..