C++ Logo

std-proposals

Advanced search

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

From: Robin Savonen Söderholm <robinsavonensoderholm_at_[hidden]>
Date: Sat, 12 Oct 2024 15:35:35 +0200
I generally avoid inheritance, but it is (sadly) the only ABI-safe and
portable solution (AFAIK) to optimise away empty members.
[[no_unique_address]] is not supported by Clang for windows, MSVC only
allows the MSVC-prefixed version. But maybe I should tackle that instead...

// Robin

On Sat, Oct 12, 2024 at 3:27 PM Jonathan Wakely <cxx_at_[hidden]> wrote:

>
>
> 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:35:50