C++ Logo

std-discussion

Advanced search

Re: Surprising error about immediate-escalation

From: Keenan Horrigan <friedkeenan_at_[hidden]>
Date: Mon, 15 Jun 2026 03:09:30 +0000
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.

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 03:09:38