Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide opt-in cv-ref qualifiers forwarding for proxy::invoke #22

Closed
xiaosa-zhz opened this issue Jul 9, 2022 · 4 comments
Closed

Provide opt-in cv-ref qualifiers forwarding for proxy::invoke #22

xiaosa-zhz opened this issue Jul 9, 2022 · 4 comments

Comments

@xiaosa-zhz
Copy link

At present, proxy::invoke is always qualifier free, which makes cv-proxy useless.
The operator() of std::function and std::function_ref is always const and they use qualifiers from underlying object. The operator() of std::move_only_function forwards cv-ref to call underlying object. Existing implementation indicates that forwarding of quals should be an opt-in mechanism.

@mingxwa
Copy link
Collaborator

mingxwa commented Jul 9, 2022

At present, proxy::invoke is always qualifier free, which makes cv-proxy useless.

I do not see why this is important. I understand that the signature of proxy::invoke may feel strange because it looks quite different from the existing facilities, say std::function::operator(), this is because the proxy is based on pointer semantics, while std::function and std::move_only_function are based on value semantics. Although proxy::invoke is qualifier-free, one can always add such qualifiers to the underlying values without making the proxy a different type, like std::move_only_function does on its template. On the other hand, if you do want to call proxy::invoke with a cv-qualified value (although I could not think of a meaningful use case), you can always const_cast.

The operator() of std::function and std::function_ref is always const and they use qualifiers from underlying object.

Maybe not. See the following example:

struct Foo {
  void operator()() { puts("non-const"); }
  void operator()() const { puts("const"); }
};
const Foo foo{};
foo();  // prints "const"
std::function<void()> f = foo;
f();  // prints "non-const"
std::as_const(f)();  // prints "non-const"

Existing implementation indicates that forwarding of quals should be an opt-in mechanism.

The proxy supports the mechanism as well, but in a different way. The qualifier on the value is determined by two factors:

  1. the qualifier that *p indicates, where p is the underlying pointer stored in an object of proxy.
  2. the constraints (any qualifiers, overloads, requires clauses, etc.) on a dispatch, see samples/resource_dictionary/main.cpp.

@xiaosa-zhz
Copy link
Author

That example makes sense to me, thanks.
If proxy somehow models a pointer, shouldn't proxy::invoke always be const? Since operator* and operator-> of built-in pointer and fancy pointers are always const qualified, and const-ness of pointers does not affect accessing object which they points to.

@mingxwa
Copy link
Collaborator

mingxwa commented Jul 9, 2022

That example makes sense to me, thanks.

You are welcome :)

If proxy somehow models a pointer, shouldn't proxy::invoke always be const?

It is not always true. There is no constraint in the standard that operator* of a fancy pointer shall always be const, like iterators and std::optional. In the implementation details of make_proxy, you can also see such design in details::sbo_ptr, which stores the value inside a pointer to avoid unnecessary heap allocation.

@mingxwa
Copy link
Collaborator

mingxwa commented Jul 9, 2022

Actually, this is a very good question. Before we adopted the design to make proxy::invoke unqualified, we attempted to add cv qualifiers from the proxy side (see revision 4 of the paper: wg21.link/p0957r4) but found it will only add complexity to the whole design, making it harder to learn without improving usability. Thank you for your interest in our work. Please let us know if there is any other comments or feedback!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants