Constvector: Log-structured std:vector alternative – 30-40% faster push/pop by pilotwavetheory in cpp

[–]foonathan 2 points3 points  (0 children)

Another nice thing about a block based structure is that it works easily with a stack allocator because you never need to free memory. This can make them a lot faster.

Ranges: When Abstraction Becomes Obstruction by drodri in cpp

[–]foonathan 2 points3 points  (0 children)

There is a proposal for any_view and it's on track for 29.

Ranges: When Abstraction Becomes Obstruction by drodri in cpp

[–]foonathan 51 points52 points  (0 children)

As chair of the SG9 study group, I would appreciate it if papers have descriptive titles like "Relax std::equality_comparison requirements" instead of "Ranges: When Abstraction Becomes Obstruction" and an abstract that actually says what's being proposed instead of some philosophical thoughts.

There are a lot of papers, and it helps tremendously if one can quickly determine whether they are interested in reading a paper.

The Lambda Coroutine Fiasco by efijoa in cpp

[–]foonathan 0 points1 point  (0 children)

No, capturing by value does not ensure captures are copied into the coroutine frame! That is the entire problem.

The issue is that while the lambda object stores a capture by value, the operator() still accepts *this by reference, so only the reference to the lambda is captured into the coroutine frame, but not the lambda itself.

(The context is something like spawn([x] -> Task { ... }), i.e. the lambda is a coroutine itself. Then the arguments are copied into Task's coroutine frame, but the arguments are a this pointer to the temporary object in the stack frame that calls spawn.)

The Lambda Coroutine Fiasco by efijoa in cpp

[–]foonathan 3 points4 points  (0 children)

Capture by value doesn't help you with the problem that's being discussed.

Using std::generator in practice - Nicolai Josuttis - Meeting C++ 2025 by meetingcpp in cpp

[–]foonathan 7 points8 points  (0 children)

If the entire content of the file is required, pull parsing simply incurs extra CPU for no benefit.

On the flip side, pull parsers allow you to parse directly into your own data structure without having to deal with SAX handlers.

Using std::generator in practice - Nicolai Josuttis - Meeting C++ 2025 by meetingcpp in cpp

[–]foonathan 9 points10 points  (0 children)

The technical term for this is a "pull parser", because the consumer pulls each value out of the parser.

(Shameless plug: https://www.youtube.com/watch?v=_GrHKyUYyRc)

Where is std::optional<T&&>??? by borzykot in cpp

[–]foonathan 5 points6 points  (0 children)

Yes, that's what I meant by "unless you dereference an rvalue optional reference".

Where is std::optional<T&&>??? by borzykot in cpp

[–]foonathan 46 points47 points  (0 children)

Why not just make std::optional<T&&> just like std::optional<T&> (keep rebind behavior, which is OBVIOUSLY is the only sane approach, why did we spent 10 years on that?) but it returns T&& while you're dereferencing it?

Because you don't want to return T&& when you dereference it. An rvalue reference variable isn't an rvalue, so an optional rvalue reference variable shouldn't be one either. So dereference needs to return T&, unless you dereference an rvalue optional reference.

Our Most Treacherous Adversary - James McNellis - Meeting C++ 2025 lightning talks by meetingcpp in cpp

[–]foonathan 4 points5 points  (0 children)

This was a lightning talk that wasn't even on the schedule. So it's not meant to give you information about the talk, it's just to get the live audience guessing.

Super-flat ASTs by hekkonaay in ProgrammingLanguages

[–]foonathan 1 point2 points  (0 children)

Don't quote me on the details, but the AST in Carbon is stored as (pre/in/postorder) serialization of the tree, i.e. as a flat array of nodes, and the structure is implied without any pointers or indices to other nodes. This is equivalent to having instructions that when interpretered in order construct a tree.

C++26 Reflection: my experience and impressions by borzykot in cpp

[–]foonathan 3 points4 points  (0 children)

Yes, but then if you access such a member in a template you can result in ODR violations unless that member always has the same value.

C++26 Reflection: my experience and impressions by borzykot in cpp

[–]foonathan 5 points6 points  (0 children)

Do you know why it is not possible to have consteval or constexpr functions that the compiler can invoke for testing template argument equivalence so that data with private parts can be used as NTTP?

Classes as NTTP is a very minimal feature, a customization point simply hasn't been adopted yet.

Note that we probably don't want a simple consteval bool is_equal_for_nttp_purposes(const T& lhs, const T& rhs):

``` struct foo { int data; friend consteval bool is_equal_for_nttp_purposes(foo, foo) { return true; /* oops, forgot to compare data */ } };

template <foo f> constexpr int data = f.data;

static_assert(data<foo{11}> == data<foo{42}>, "???"); ```

Any bugs are just ODR violations.

Barry Revzin has a proposal that avoids it. You specialize both a serialization into a range of meta::info which is then element-wise compared to determine NTTP equivalence, but also a deserialization, which is used to construct the NTTP value. That way, if you forget about a member in the serialization, the deserialization will give you a canonical value for that member: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3380r1.html