Date: Wed, 7 May 2025 14:14:48 -0400
On Wed, May 7, 2025 at 11:12 AM Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:
> On Wed, May 7, 2025 at 2:44 AM Arthur O'Dwyer wrote:
> >
> > There is; check out the "passkey idiom."
> >
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2893r3.html#passkey-idiom
>
> I read your paper just now. I wonder had you considered excluding
> certain classes with a 'requires' clause? Let's say you only want to
> be friends with classes that have a 'value' that is a pointer to a
> polymorphic class. So where you had:
>
> template<class... Ts>
> class Foo {
> friend Ts...;
> };
>
> Imagine if you could have:
>
> template<class... Ts>
> class Foo {
> (friend Ts requires (is_pointer_v< Ts::value > &&
> is_polymorphic_v< remove_pointer_t<Ts::value> >) ). . . ;
> };
>
> Something along those lines.
>
That thing with the parentheses isn't remotely how C++'s declaration
grammar works, though, so, no.
It might be plausible to befriend a bunch of template specializations by
pretending to befriend an explicit specialization or partial
specialization, like this:
template<class> struct A;
class B {
static int f();
template<> friend struct A<int>; // invalid today, but hypothetically
this could become legal
template<class T> requires (sizeof(T) == 1) friend struct A<T>; //
invalid today, but hypothetically this could become legal
};
template<> struct A<int> {
static int g(B *b) { return b->f(); } // hypothetically, this would
become accessible
};
template<> struct A<char> {
static int g(B *b) { return b->f(); } // even more hypothetically, this
would become accessible (even though the befriender used
partial-specialization syntax and this is an explicit specialization)
};
template<> struct A<short> {
static int g(B *b) { return b->f(); } // remains ill-formed because B::f
is inaccessible to this specialization
};
But that has nothing to do with "variadic friend"; that would be a
completely different feature, completely different syntax.
–Arthur
Std-Proposals <std-proposals_at_[hidden]> wrote:
> On Wed, May 7, 2025 at 2:44 AM Arthur O'Dwyer wrote:
> >
> > There is; check out the "passkey idiom."
> >
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2893r3.html#passkey-idiom
>
> I read your paper just now. I wonder had you considered excluding
> certain classes with a 'requires' clause? Let's say you only want to
> be friends with classes that have a 'value' that is a pointer to a
> polymorphic class. So where you had:
>
> template<class... Ts>
> class Foo {
> friend Ts...;
> };
>
> Imagine if you could have:
>
> template<class... Ts>
> class Foo {
> (friend Ts requires (is_pointer_v< Ts::value > &&
> is_polymorphic_v< remove_pointer_t<Ts::value> >) ). . . ;
> };
>
> Something along those lines.
>
That thing with the parentheses isn't remotely how C++'s declaration
grammar works, though, so, no.
It might be plausible to befriend a bunch of template specializations by
pretending to befriend an explicit specialization or partial
specialization, like this:
template<class> struct A;
class B {
static int f();
template<> friend struct A<int>; // invalid today, but hypothetically
this could become legal
template<class T> requires (sizeof(T) == 1) friend struct A<T>; //
invalid today, but hypothetically this could become legal
};
template<> struct A<int> {
static int g(B *b) { return b->f(); } // hypothetically, this would
become accessible
};
template<> struct A<char> {
static int g(B *b) { return b->f(); } // even more hypothetically, this
would become accessible (even though the befriender used
partial-specialization syntax and this is an explicit specialization)
};
template<> struct A<short> {
static int g(B *b) { return b->f(); } // remains ill-formed because B::f
is inaccessible to this specialization
};
But that has nothing to do with "variadic friend"; that would be a
completely different feature, completely different syntax.
–Arthur
Received on 2025-05-07 18:15:04