Date: Mon, 15 Jun 2026 11:30:47 +0100
On 15/06/2026 04:09, Keenan Horrigan wrote:
> My apologies, it turns out that what I had thought was a reduced form of my problem actually wasn't. The following would appear to be the *actual* reduced form of the problem I'm facing:
>
> #include <meta>
> #include <functional>
>
> template<typename F>
> requires (std::invocable<F &, const int &>)
> constexpr auto caller(F f, const int x) -> decltype(auto) {
> f(x);
> }
>
> int main(int argc, char **) {
> caller([](auto) {
> (void) display_string_of(std::meta::current_function());
> }, argc);
> }
>
> Godbolt link: https://godbolt.org/z/oao7x8GYe
>
> If one removes the 'requires' clause on the 'caller' function, or changes the called lambda to not be templated, then the code successfully compiles.
Adding a trailing void return type to the lambda also works around the issue.
https://godbolt.org/z/6Pnd3v511
I suspect that this is related to return type deduction and hence early instantiation of
the function body, possibly with some circular dependency there, but I didn't look deeply
into it now.
>
> However, it also compiles if one calls 'std::meta::access_context::current.scope()' instead of current_function(). Which leads me to believe that this is a GCC bug, and not a fault of the standard. So I'll be reporting this to GCC.
>
> Sorry for the trouble.
>
> On Sunday, June 14th, 2026 at 5:30 PM, Lénárd Szolnoki <cpp_at_[hidden]> wrote:
>
>>
>>
>> On 14/06/2026 09:22, Keenan Horrigan via Std-Discussion wrote:
>>> Hi,
>>>
>>> I'm trying to use std::meta::current_function in a default parameter so that I can pack certain compile-time information about the calling-function into an object that I can then access at runtime.
>>>
>>> And what I have seems to work great, but I just ran into a case involving templated functions where the compiler ends up telling me that it escalated a function to consteval, and so I can't actually call it at runtime.
>>>
>>> I've reduced the issue to the following code:
>>>
>>> #include <meta>
>>>
>>> struct blah {
>>> consteval blah(std::meta::info f = std::meta::current_function()) {
>>> (void) identifier_of(f);
>>> }
>>> };
>>>
>>> constexpr void bar(int, blah = {}) {}
>>>
>>> constexpr void foo(auto x) {
>>> bar(x);
>>> }
>>>
>>> int main(int argc, char **) {
>>> foo(argc);
>>> }
>>>
>>> And here's a godbolt link: https://godbolt.org/z/dPE9PPT6P
>>>
>>> Both GCC and Clang (if one translates the call to std::meta::current_function to one involving std::meta::access_context::current) emit an error for this code pertaining to immediate-escalation.
>>>
>>> If one were to either make 'foo' not templated, or were to remove the 'identifier_of(f)' call in the 'blah' constructor, then the code would compile successfully.
>>>
>>> So I guess I'm wondering:
>>>
>>> 1. Why is this happening? It does not feel very intuitive to me. (And a corollary to this question, is this behavior intentional?)
>>
>> `identifier_of` throws `std::meta::exception` for a function template specialisation, as
>> `has_identifier` is false for it. It makes the constructor call to `blah` not a constant
>> expression, so it escalates, hence the confusing error.
>>
>>> 2. Is there a way for me to avoid this behavior, and still get my runtime-accessible description of the function in templated contexts?
>>
>> You can look at `has_template_arguments`, `template_of` and `template_arguments_of` and
>> decide what to do with them.
>>
>> You can call `identifier_of(template_of(f))` in your example: https://godbolt.org/z/784Wz4Woz
>>
>>> Any clarification on those questions would be very greatly appreciated.
>>>
>>> Thanks
>>> --
>>> Std-Discussion mailing list
>>> Std-Discussion_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>
>>
> My apologies, it turns out that what I had thought was a reduced form of my problem actually wasn't. The following would appear to be the *actual* reduced form of the problem I'm facing:
>
> #include <meta>
> #include <functional>
>
> template<typename F>
> requires (std::invocable<F &, const int &>)
> constexpr auto caller(F f, const int x) -> decltype(auto) {
> f(x);
> }
>
> int main(int argc, char **) {
> caller([](auto) {
> (void) display_string_of(std::meta::current_function());
> }, argc);
> }
>
> Godbolt link: https://godbolt.org/z/oao7x8GYe
>
> If one removes the 'requires' clause on the 'caller' function, or changes the called lambda to not be templated, then the code successfully compiles.
Adding a trailing void return type to the lambda also works around the issue.
https://godbolt.org/z/6Pnd3v511
I suspect that this is related to return type deduction and hence early instantiation of
the function body, possibly with some circular dependency there, but I didn't look deeply
into it now.
>
> However, it also compiles if one calls 'std::meta::access_context::current.scope()' instead of current_function(). Which leads me to believe that this is a GCC bug, and not a fault of the standard. So I'll be reporting this to GCC.
>
> Sorry for the trouble.
>
> On Sunday, June 14th, 2026 at 5:30 PM, Lénárd Szolnoki <cpp_at_[hidden]> wrote:
>
>>
>>
>> On 14/06/2026 09:22, Keenan Horrigan via Std-Discussion wrote:
>>> Hi,
>>>
>>> I'm trying to use std::meta::current_function in a default parameter so that I can pack certain compile-time information about the calling-function into an object that I can then access at runtime.
>>>
>>> And what I have seems to work great, but I just ran into a case involving templated functions where the compiler ends up telling me that it escalated a function to consteval, and so I can't actually call it at runtime.
>>>
>>> I've reduced the issue to the following code:
>>>
>>> #include <meta>
>>>
>>> struct blah {
>>> consteval blah(std::meta::info f = std::meta::current_function()) {
>>> (void) identifier_of(f);
>>> }
>>> };
>>>
>>> constexpr void bar(int, blah = {}) {}
>>>
>>> constexpr void foo(auto x) {
>>> bar(x);
>>> }
>>>
>>> int main(int argc, char **) {
>>> foo(argc);
>>> }
>>>
>>> And here's a godbolt link: https://godbolt.org/z/dPE9PPT6P
>>>
>>> Both GCC and Clang (if one translates the call to std::meta::current_function to one involving std::meta::access_context::current) emit an error for this code pertaining to immediate-escalation.
>>>
>>> If one were to either make 'foo' not templated, or were to remove the 'identifier_of(f)' call in the 'blah' constructor, then the code would compile successfully.
>>>
>>> So I guess I'm wondering:
>>>
>>> 1. Why is this happening? It does not feel very intuitive to me. (And a corollary to this question, is this behavior intentional?)
>>
>> `identifier_of` throws `std::meta::exception` for a function template specialisation, as
>> `has_identifier` is false for it. It makes the constructor call to `blah` not a constant
>> expression, so it escalates, hence the confusing error.
>>
>>> 2. Is there a way for me to avoid this behavior, and still get my runtime-accessible description of the function in templated contexts?
>>
>> You can look at `has_template_arguments`, `template_of` and `template_arguments_of` and
>> decide what to do with them.
>>
>> You can call `identifier_of(template_of(f))` in your example: https://godbolt.org/z/784Wz4Woz
>>
>>> Any clarification on those questions would be very greatly appreciated.
>>>
>>> Thanks
>>> --
>>> Std-Discussion mailing list
>>> Std-Discussion_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>
>>
Received on 2026-06-15 10:30:58
