[HN Gopher] C++26: Pack Indexing
___________________________________________________________________
C++26: Pack Indexing
Author : HeliumHydride
Score : 49 points
Date : 2025-01-24 19:27 UTC (3 hours ago)
(HTM) web link (www.sandordargo.com)
(TXT) w3m dump (www.sandordargo.com)
| foota wrote:
| This is nice, but I'm still waiting for a constexpr for loop to
| use it with.
| mystified5016 wrote:
| Can we have constexpr math functions like sqrt already?
| Maxatar wrote:
| My understanding is that all of the functions found in the C
| compatibility headers that the C++ standard defines can not
| be made constexpr. sqrt is among them, as are a lot of the
| math functions.
| agosz wrote:
| The compatibility can be solved with macros to toggle it on
| or off depending on how you're building. C++26 has
| constexpr sqrt.
| pjmlp wrote:
| There is a paper suggesting to replace all macro based
| code, due to way modules work.
|
| https://www.open-
| std.org/jtc1/sc22/wg21/docs/papers/2025/p26...
| stefanos82 wrote:
| Seems like since C++26, it does use constexpr
| https://en.cppreference.com/w/cpp/numeric/math/sqrt
| logicchains wrote:
| If you want to iterate over the whole thing you can just use a
| fold expression, which arguably look cleaner than the non-
| compiletime ways to map over a collection like std::transform.
| a_t48 wrote:
| Even with fold expressions, sometimes you need the actual
| index. See here https://github.com/basis-
| robotics/basis/blob/ca70aee6daca37c... - I did use a fold
| expression, but I needed the actual index in the fold
| expression to both do array access and to pass down into a
| template parameter.
| foota wrote:
| Arguably is doing a lot of work here, peoples eyes tend to
| start glazing over when I tell them it's a parameter pack
| fold :) I'd much rather have a loop that doesn't confuse
| people not familiar with the syntax.
| a_t48 wrote:
| Pretty please. [&]<std::size_t...
| I>(std::index_sequence<I...>) {
| (SetupInput<I>(options, transport_manager,
| subscriber_queues[I], thread_pool,
| templated_topic_to_runtime_topic), ...);
| }(std::make_index_sequence<INPUT_COUNT>());
|
| would be a lot more readible as for
| constexpr( size_t I = 0; I < INPUT_COUNT; I++ )
| SetupInput<I>(options, transport_manager, subscriber_queues[I],
| thread_pool, templated_topic_to_runtime_topic); }
|
| Yes, there's some syntax snags around it (right now I looks
| mutable, something like `for (constexpr size_t I :
| INPUT_COUNT)` might be better), but there has to be some sane
| middleground.
| moonshadow565 wrote:
| P1061 is in C++26 so you can instead do:
| const auto [...I] = std::make_index_sequence<INPUT_COUNT>{};
| ((SetupInput<I>(options, transport_manager,
| subscriber_queues[I], thread_pool,
| templated_topic_to_runtime_topic)),...);
|
| yay!
| foota wrote:
| Oh, that is nice!
| spacechild1 wrote:
| > right now I looks mutable, something like `for (constexpr
| size_t I : INPUT_COUNT)` might be better
|
| I thought the same, but then you lose the ability to control
| the increment step. For example, one might want to iterate
| pairwise.
|
| Regarding syntax, you could mandate that the loop variable
| has to be declared `constexpr` as well, which makes it clear
| that it can't be modified in the loop body.
| pragma_x wrote:
| It's been ages since I've done metaprogramming with C++. I had
| to look this up, since my first reaction was: just use
| recursion! Yeah, I can see why a for-loop is the preferred way
| to go here.
|
| Turns out that const-call depth is limited to 512, but by
| implementation, not by the standard (which is undefined).
|
| https://stackoverflow.com/a/9320911/713831
| foota wrote:
| There's a way to "iterate" over parameter packs called fold
| expressions, but they're painful and look very weird.
| plorkyeran wrote:
| I don't find them painful, but they're definitely extremely
| weird looking. The fact that they're "fold expressions" but
| are normally used with operator comma to sequence together
| things that want to be statements is a pretty strong sign
| that something went wrong in the design process.
| beached_whale wrote:
| template for is proposed for 26 as part of the reflection
| papers.
| edflsafoiewq wrote:
| C++ continues its long journey to making its template system an
| actual usable programming language.
| kubb wrote:
| It's unfortunate that it had to happen by accident, and now new
| features are reluctantly being pushed through piecemeal.
|
| Imagine what it could have been if it was designed for
| programmability from the start.
| klipt wrote:
| > Imagine what it could have been if it was designed for
| programmability from the start.
|
| Circle C++ compiler was designed for that:
| https://www.circle-lang.org/quickref.html
| nxobject wrote:
| I do think as well that some deeper scrutiny of semantics
| with the tools of PL research might have helped ahead of time
| - some of the most glaring warts like the perfect forwarding
| problem, or the need for reference collapsing, would have
| been avoided if the standards committee had taken a more
| rigorous approach to understanding semantics and their
| implications. I hope Zig's comptime will get that level of
| scrutiny.
| kazinator wrote:
| It would have been a huge, sudden increment in complexity
| from absolute zero, causing it to be forever written off and
| ignored as an incomprehensible curiosity looking for a
| practical application.
|
| You have to suck people in with, "hey, you can write these
| two similar C-like functions under one definition, the
| correct one of which is automatically deduced and used".
| papichulo2023 wrote:
| I like to code in cpp as a hobby (computer vision stuff) but
| avoid template programing like the plague. The part of std is
| already scary stuff with 50 lines of errors for single typo.
| edflsafoiewq wrote:
| It's actually becoming easier as they make it a real
| programming language.
|
| The infamous template error messages are generally a result
| of two things: first, too many candidate functions because
| logic is cobbled together out of a nest of SFINAE overloads,
| which is ameliorated by moving the logic into normal code
| with if constexpr, etc; and second, type errors occurring
| deep in the call/expansion stack because unchecked values
| keep getting passed on just like in a dynamically typed
| language (which TMP basically is), which is ameliorated by
| moving the type checks higher up in the stack with concepts
| or static_assert.
| mb7733 wrote:
| > 50 lines of errors for single typo
|
| 50? That's it!? I work in a code base where a previous
| developer went nuts with overloads and I routinely get
| hundreds of lines of output for a single compiler error.
| npalli wrote:
| >The part of std is already scary stuff with 50 lines of
| errors for single typo.
|
| IDE's make this less of a problem.
| dkersten wrote:
| I personally quite like templates and constexpr. I don't do
| anything too crazy with them, but I like being able to write
| code that will compile down to efficient code without runtime
| checks. I tried to write equally generic code in typescript
| recently and I had to make peace with the fact that I had to
| pay for either an indirect call through inheritance or a
| runtime conditional, where in C++ I could use template code
| and a constexpr if to choose the correct code path at compile
| time.
| rerdavies wrote:
| I code cpp professionally. But I still dread template
| programming. Pretty much a guarantee that I'm going to end up
| spending an afternoon wading through horrifyingly inscrutable
| error messages.
| pjmlp wrote:
| After C++17, template programming has become relatively easy.
|
| You can use enable_if and static_assert, alongside type
| traits to check the types, and give useful error messages.
|
| With C++20 you get concepts lite, which while not being as
| good as C++0x concepts, still simplify the code a lot,
| improve error messages, and remove the need for the classical
| tricks, when used alongside constexpr.
|
| No need to go crazy with them.
| paulddraper wrote:
| Save often, compile often
| dgfitz wrote:
| I also refuse to touch templates. Never needed them, never
| liked them. When I work on code that utilizes templates in
| c++, it reaffirms this feeling.
| mianos wrote:
| 50 lines? For std io I get 100s of lines of candidate
| suggestions. It's so dumb. I usually turn off the suggestions
| error. Only about 35 years as a C++ developer so maybe I will
| become less grumpy about template errors as I age.
| pjmlp wrote:
| Which I actually find more approachable than how Rust deals
| with two macros systems, each with its own mini language.
|
| At least, as convuluted as C++ may be, template and compile
| time programming still rely on C++.
| necubi wrote:
| I'm not necessarily going to defend proc macros, which have a
| lot of problems but are also better than the alternative in
| many languages (like Go's over-reliance on codegen). Macros-
| by-example are pretty nice though, even with the special
| syntax.
|
| But in Rust, you don't need to delve into any kind of macro
| for polymorphism like you do in C++, since Rust has a real
| generics system. There is vastly more C++ code that
| instantiates templates than Rust code that uses macros.
| pjmlp wrote:
| There are enough ways to do polymorphism in C++ without
| touching macros.
|
| Given that Rust IO and many crate attributes are macro
| based, not sure who wins out.
| necubi wrote:
| I was a bit unclear there--I was referring to templates,
| not C++ macros. I believe that concepts in C++20 have
| improved the situation (although I haven't personally
| worked with a C++20 codebase and don't know how widely
| adopted it is in the ecosystem).
| cherryteastain wrote:
| In modern C++, you don't need macros for polymorphism at
| all
| marginalia_nu wrote:
| Unless this is about some particular technique I've
| missed, isn't this what virtual methods are for? Only
| place I'm aware of where you see macros-based
| polymorphism is in C.
| cherryteastain wrote:
| Virtual methods are runtime polymporphism. Templates are
| compile time polymorphism, and therefore typically are
| faster (more inlining + avoiding virtual function call).
| jovial_cavalier wrote:
| Am I crazy for thinking this is (mostly) useless?
|
| It feels like programming in the last five years has turned
| into a competition of who can make the most abstract meta
| programming patterns. I think if you find yourself making use
| of this feature, you're probably in a deep hole of your own
| making.
|
| What is an example of a useful function that takes an arbitrary
| number of arguments each of which has an arbitrary type that
| isn't as trivial as the examples given in the article? For
| super trivial stuff this is useful, and if std used this under
| the hood to provide std::first_arg or something, that would
| make sense. But the absence of this language feature doesn't
| really seem like it's holding back 99.9% of users.
| foota wrote:
| People writing generic libraries need this. As an example,
| I've seen it used a lot in anything related to logging and
| monitoring, since these generally need the ability to take
| arbitrary data types and work with them in different ways.
| The same is true for database APIs, etc.,.
| HeliumHydride wrote:
| std::print is one. You need variadic generics to make it
| work.
| suby wrote:
| I don't have a source, but I have read that the reason this
| wasn't originally introduced into C++ was because they couldn't
| agree on what the syntax would be. So much pain because the
| committee is dysfunctional, it took a decade plus to introduce
| something that everyone from the start wanted and understood
| would improve things. Par for the course with C++.
| rerdavies wrote:
| At least it's progress over the first decade of C++'s life
| where NOTHING happened.
| spacechild1 wrote:
| > I don't have a source, but I have read that the reason this
| wasn't originally introduced into C++ was because they couldn't
| agree on what the syntax would be
|
| I can totally imagine that. That's double ironic because the
| syntax is pretty obvious (which I find pretty surprising for a
| new C++ feature :)
|
| But yeah, it's amazing that we only get this 15 years(!) after
| the introduction of variadic templates. I can totally see why
| some languages would decide against ISO standardization.
| mkoubaa wrote:
| Suppose c++ is around for 100 more years (i'll take the over).
|
| Sacrificing a couple decades in order to get the syntax just
| right is worth it. Just look at... Javascript.
| int_19h wrote:
| Yeah, but then look at C++ - does the syntax really look like
| it's "just right" to you? Modern JS features actually tend to
| have cleaner syntax, generally speaking.
| a_t48 wrote:
| I usually find myself putting parameter packs into tuples and
| then using `std::get` on the tuple to index. It's not perfect
| (will end up making copies), but has the side benefit of being
| able to additionally store the parameter pack for later.
| int_19h wrote:
| Zig's approach to generics and metaprogramming - treating
| functions and types as first-class compile-time values in the
| base language - makes more and more sense.
| psyclobe wrote:
| C++ parameter packs are really bad ass, super cool to see this
| added
___________________________________________________________________
(page generated 2025-01-24 23:00 UTC)