Why does the standard not consider functors with a ref-qualified call operator to be invocable?
#include <concepts>
struct f { auto operator()() {} };
struct fr { auto operator()() & {} };
struct fcr { auto operator()() const& {} };
struct frr { auto operator()() && {} };
static_assert(std::copy_constructible<f>); // ok
static_assert(std::copy_constructible<fr>); // ok
static_assert(std::copy_constructible<fcr>); // ok
static_assert(std::copy_constructible<frr>); // ok
static_assert(std::invocable<f>); // ok
static_assert(std::invocable<fr>); // fails
static_assert(std::invocable<fcr>); // ok
static_assert(std::invocable<frr>); // ok
Well it might have something to do with std::declval returning a temporary object, I don't feel an implementation detail as such should be relevant to the user. Semantically, the functors in the example code should not be regarded differently in terms of invocability.
Also, why does there appear to be this contradiction between what std::invocable and std::function consider to be a callable object?
#include <functional>
using tf = decltype(std::function{f{}}); // ok
using tfr = decltype(std::function{fr{}}); // ok
using tfcr = decltype(std::function{fcr{}}); // ok
using tfrr = decltype(std::function{frr{}}); // fails
Just to muddy the waters even further, it also seems that MVSC v19.32 accepts the following code. Is that simply a compiler bug of MSVC?
template<std::invocable F>
auto g() -> void {}
using tg = decltype(g<f>); // ok
using tgr = decltype(g<fr>); // ok
using tgcr = decltype(g<fcr>); // ok
using tgrr = decltype(g<frr>); // ok