Date: Fri, 28 Feb 2025 10:47:40 -0500
I tried looking at the reflection papers to see if I could remedy this, and
I think you could write a macro using token injection such as
consteval std::meta::info overload_set(std::meta::info name) {
return ^{ [](auto&&... args) -> decltype(auto) {
return [:\tokens(name):](std::forward<decltype(args)>(args)...);
} };
}
This could be used as follows:
std::function<void(int)> f = overload_set!(g);
I think it would be much terser than writing out an entire lambda (in this
case, a cast would be preferable anyway), and it sidesteps common pitfalls
like incurring unnecessary copies by forgetting to perfectly forward the
arguments or returning decltype(auto).
I think token reflection is required because it seems that if id-expression
denotes an overload set, then ^^id-expression must result in a unique
overload to be well-formed, but I'm not an expert on reflection.
Has something like this been proposed or discussed? Of course, you could
also do it with C-style macros, but I suspect that would be more
controversial.
On Thu, Feb 27, 2025, 4:55 AM Jonathan Wakely <cxx_at_[hidden]> wrote:
>
>
> On Thu, 27 Feb 2025, 02:39 Jack O'Donohue via Std-Proposals, <
> std-proposals_at_[hidden]> wrote:
>
>> Someone said this could be considered a defect, but it seems more like a
>> proposal to me, especially with pointers to members.
>>
>
> It's not a defect, the original design is working as intended. You're
> proposing a change to the design.
>
> My main concern is that you don't always use exactly the same signature
> with the std::function as the target that you construct it with. For
> example, you might have a function of type const int&(const int&) and want
> to store it in std::function<long(int)>. Your new constructors wouldn't
> help here.
>
>
>
I think you could write a macro using token injection such as
consteval std::meta::info overload_set(std::meta::info name) {
return ^{ [](auto&&... args) -> decltype(auto) {
return [:\tokens(name):](std::forward<decltype(args)>(args)...);
} };
}
This could be used as follows:
std::function<void(int)> f = overload_set!(g);
I think it would be much terser than writing out an entire lambda (in this
case, a cast would be preferable anyway), and it sidesteps common pitfalls
like incurring unnecessary copies by forgetting to perfectly forward the
arguments or returning decltype(auto).
I think token reflection is required because it seems that if id-expression
denotes an overload set, then ^^id-expression must result in a unique
overload to be well-formed, but I'm not an expert on reflection.
Has something like this been proposed or discussed? Of course, you could
also do it with C-style macros, but I suspect that would be more
controversial.
On Thu, Feb 27, 2025, 4:55 AM Jonathan Wakely <cxx_at_[hidden]> wrote:
>
>
> On Thu, 27 Feb 2025, 02:39 Jack O'Donohue via Std-Proposals, <
> std-proposals_at_[hidden]> wrote:
>
>> Someone said this could be considered a defect, but it seems more like a
>> proposal to me, especially with pointers to members.
>>
>
> It's not a defect, the original design is working as intended. You're
> proposing a change to the design.
>
> My main concern is that you don't always use exactly the same signature
> with the std::function as the target that you construct it with. For
> example, you might have a function of type const int&(const int&) and want
> to store it in std::function<long(int)>. Your new constructors wouldn't
> help here.
>
>
>
Received on 2025-02-28 15:47:56