C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Access-level aware concepts

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Sat, 12 Oct 2024 14:26:12 +0100
On Sat, 12 Oct 2024 at 14:22, Jonathan Wakely <cxx_at_[hidden]> wrote:

>
>
> On Sat, 12 Oct 2024 at 14:05, Robin Savonen Söderholm via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> Hi!
>> I can't seem to find any information about how constraints and class
>> access specifiers could work together. Currently it seems like concepts are
>> always evaluated from "outside" a class (i.e. only public fields and
>> methods affect the evaluation of the constraint).
>>
>
> Correct. That's essential to be able to cache the result, you don't want
> foo<T> to mean different things depending on where the first check happens,
> and you don't want the result to not be memoized (for performance during
> compilation).
>
>
>
>> E.g. for example:
>> ```c++
>>
>> #include <concepts>
>> #include <utility>
>>
>> class clazz_with_protected_ctor {
>> protected:
>> explicit clazz_with_protected_ctor(int) {}
>> };
>>
>> template <typename T>
>> struct clazz_wrapper: private T {
>> template <typename... Ts>
>> requires(std::constructible_from<T, Ts&&...>) explicit
>> clazz_wrapper(Ts&&... args) : T(std::forward<T>(args)...) {}
>> };
>>
>> void foo() {
>> // Generates compile-error since the constraint for the constructor can't
>> see the protected constructor
>> auto my_wrapper = clazz_wrapper<clazz_with_protected_ctor>(1);
>> }
>> ```
>>
>> I wonder if not the above code should actually be a sensible piece of
>> code (especially with CRTP-based API:s), and it may be needed that
>> constraints are evaluated from the context that they are used.
>>
>
> Inheritance is an incredibly strong coupling, the strongest in C++. It
> doesn't really make sense to be inheriting from types where you don't know
> whether you can use a protected (or private, via friendship) API. Either
> inherit from arbitrary types provided as template args and rely on the
> members you need being public
>

I should have said "being accessible" rather than necessarily public. It's
fine if the member you need to use is protected, because the derived class
will be able to use it. It doesn't make sense to query whether it's usable
though. If you're inheriting,the member you need to use need to be
accessible

N.B. In the example above, you could just do `using T::T;` to get the
desired effects. So you don't need to test for the constructor being usable.



> , or don't inherit.
>

Received on 2024-10-12 13:27:29