• Is this even legal?

    From Chris M. Thomasson@3:633/10 to All on Sat Oct 3 17:15:45 2026
    Wondering about how the local struct can be extended out of the
    function. auto magic? ;^) Here is some example code: _____________________________
    #include <iostream>

    namespace ct_misc
    {
    template<
    typename T0,
    typename T1,
    typename T2
    > struct pack
    {
    T0 m_t0 = { };
    T1 m_t1 = { };
    T2 m_t2 = { };
    };


    template<
    typename T0,
    typename T1,
    typename T2
    >
    static auto
    pack_it(
    T0 const& t0,
    T1 const& t1,
    T2 const& t2
    ) {
    return pack<T0, T1, T2> { t0, t1, t2 };
    }


    auto
    manifest()
    {
    struct foo
    {
    int x = 0;

    void
    duck()
    {
    std::cout << "x = " << x << "\n";
    }
    };

    return pack_it(1u, .5f, foo{});
    }
    }

    int main()
    {
    auto foobar = ct_misc::manifest();

    std::cout << "foobar.m_t0 = " << foobar.m_t0 << "\n";
    std::cout << "foobar.m_t1 = " << foobar.m_t1 << "\n";
    foobar.m_t2.duck();

    return 0;
    }
    _____________________________


    I get:

    foobar.m_t0 = 1
    foobar.m_t1 = 0.5
    x = 0




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sat Oct 3 17:34:14 2026
    On 10/3/2026 5:15 PM, Chris M. Thomasson wrote:
    Wondering about how the local struct can be extended out of the
    function. auto magic? ;^) Here is some example code:
    [...]

    What about this crap?
    ________________________
    #include <iostream>

    namespace ct_misc
    {
    template<
    typename T0,
    typename T1,
    typename T2
    > struct pack
    {
    using t0 = T0;
    using t1 = T1;
    using t2 = T2;
    };


    template<
    typename T0,
    typename T1,
    typename T2
    >
    static auto
    pack_it(
    T0 const& t0,
    T1 const& t1,
    T2 const& t2
    ) {
    return pack<T0, T1, T2> {};
    }


    auto
    manifest()
    {
    struct foo
    {
    int x;

    void
    duck()
    {
    std::cout << "foo::duck() x = " << x << "\n";
    }
    };

    return pack_it(1u, .5f, foo{});
    }
    }

    int
    main()
    {
    using manifest_type = decltype(ct_misc::manifest());

    using foo_t = manifest_type::t2;

    foo_t x{ 42 };
    x.duck();

    return 0;
    }
    ________________________

    I get:

    foo::duck() x = 42


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Andrey Tarasevich@3:633/10 to All on Sun Oct 4 09:26:26 2026
    On Sat 10/3/2026 5:15 PM, Chris M. Thomasson wrote:
    Wondering about how the local struct can be extended out of the
    function. auto magic?
    Well, short answer: yes.

    It is a rather popular observation that the introduction of `decltype`
    made it much easier to break the protection formerly provided to type declarations by 'protected/private' access specifiers. Introduction of
    `auto` placeholder for function return types extended this possibility
    to local types, which before that were protected by the last remaining obstacle - impossibility to name the type.

    This is widely used to return lambda closure objects from functions.
    Note that a local lambda expression introduces an unnamed _local_ type
    into the same scope. So, when you return such closure object from a
    function (using `auto` placeholder for return type, of course), you are
    doing essentially the same thing as what your example demonstrates.

    --
    Best regards,
    Andrey



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Tue Oct 6 14:15:09 2026
    On 10/4/2026 9:26 AM, Andrey Tarasevich wrote:
    On Sat 10/3/2026 5:15 PM, Chris M. Thomasson wrote:
    Wondering about how the local struct can be extended out of the
    function. auto magic?
    Well, short answer: yes.

    It is a rather popular observation that the introduction of `decltype`
    made it much easier to break the protection formerly provided to type declarations by 'protected/private' access specifiers. Introduction of `auto` placeholder for function return types extended this possibility
    to local types, which before that were protected by the last remaining obstacle - impossibility to name the type.

    This is widely used to return lambda closure objects from functions.
    Note that a local lambda expression introduces an unnamed _local_ type
    into the same scope. So, when you return such closure object from a
    function (using `auto` placeholder for return type, of course), you are doing essentially the same thing as what your example demonstrates.


    Well, shit man. I was amazed when the "private", not so private, local
    struct with "no name" popped right out of the function. The internal
    name is private... C++ name mangles a lot?

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)