On Wed, Nov 15, 2023 at 3:34 PM Frederick Virchanza Gotham via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Wed, Nov 15, 2023 at 12:09 PM Pavel Vazharov <freakpv@gmail.com> wrote:
> #include <cstdio>
>
> template <typename Tag = decltype([]{})>
> void fun()
> {
>     static int counter = 0;
>     std::printf("addr:%p value:%i\n", &counter, counter);
> }
>
> int main()
> {
>     fun();
>     fun();
>     fun();
>
>     return 0;
> }
>
> This prints something like
>
> addr:0x40401c value:0
> addr:0x404020 value:0
> addr:0x404024 value:0

Does the Standard mandate that every C++23 compiler behaves this way?
Or does it just so happen that this code behaves the way it behaves on
all the major compilers? What I mean is: Could the compiler create the
default template argument in one place and then share that type among
the instantiations? Or, does the Standard mandate that the compiler
produce a program that behaves as though:

     fun();
     fun();
     fun();

had been written as:

     fun< decltype([]{}) >();
     fun< decltype([]{}) >();
     fun< decltype([]{}) >();

With the way the C++23 Standard is currently written, could these
three lines have the same type as the default template parameter,
almost as though it had been written:

     auto some_static_duration_lambda_object = []{};
     fun< decltype(some_static_duration_lambda_object) >();
     fun< decltype(some_static_duration_lambda_object) >();
     fun< decltype(some_static_duration_lambda_object) >();
--
As far as I know the standard mandates that every lambda has a unique type.
I don't think that the compiler is allowed to do the "collapsing" of the "same" lambda objects to a single type but I can't prove it as I'm not so versed with the C++ standard.