Skip to content

Conversation

Eczbek
Copy link

@Eczbek Eczbek commented Apr 12, 2025

No description provided.

Copy link
Member

@jeremy-rifkin jeremy-rifkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for taking the time to put this together! This looks really good! I am about halfway through reading, dropping some comments below.

{ text: "Standards", link: "/resources/general/standards" },
{
text: "C++ Resources",
items: [{ text: "Lambdas", link: "/resources/general/cpp/lambdas" }],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
items: [{ text: "Lambdas", link: "/resources/general/cpp/lambdas" }],
items: [{ text: "Lambdas", link: "/resources/cpp/lambdas" }],

@@ -0,0 +1,365 @@
## Abstract
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every page should start with an h1, that's how pages get page titles. E.g.

image

vs

image

I would also say let's not make an "abstract" section, this isn't a paper :)

captures by reference), making lambdas ideal for short, context-dependent operations like custom comparisons, filters,
or event handlers.

For example:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example comes after a couple paragraphs on captures, but doesn't use any captures. Maybe it'd be good to show this code example early on, then talk about captures, then show an example using captures?

For example:

```cpp
// Define a function in namespace scope
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm inclined to say this comment and others can be dropped, however, if anyone strongly feels this would be helpful for beginners reading the article then it's ok to keep. I think this article is a bit more of a deep-dive than beginner content, though.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments are meant to emphasize and explain the difference between the code snippets.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's pretty clear from just reading the code. Thoughts?

}
```

 
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't try to manually insert space like this :) This will introduce inconsistency with how the site presents itself.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use this as a break between paragraphs. Should I use something else or avoid breaks entirely?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’d say avoid them entirely. The site styling already handled spacing between paragraphs and headers.

The basic syntax of a lambda expression looks like this:

```
[captures](params) -> ReturnType {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[captures](params) -> ReturnType {
[captures](params) -> return_type {

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-_-


 

Each lambda expression has its own unique, unnameable type:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend moving this part to a later section as it's an implementation detail that doesn't pertain to most uses of lambdas

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where should I move this to? Also, I think showing that a lambda is really similar to a struct with an operator() is useful early on, so should I write something else here instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a later section on implementation details

Comment on lines +106 to +107
- `[x...]` - Capture a pack `x` by value.
- `[&x...]` - Capture a pack `x` by reference.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a cool bit of trivia and I had to go check the grammar about it. While this is technically its own special syntax in the standard, it's not different from a user perspective. Maybe these could be moved to a note along the lines of "Captures even work with packs!"

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea

}();
}();
```

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think another cool thing to mention in this section about captures would be that lambdas under the hood only capture what they actually use, so [&] and [=] can be used without fear of bloat or overhead

Lambda parameters work the same way as normal function parameters, and `auto` parameters make a lambda's `operator()`
implicitly templated.

If a lambda takes no parameters, the parameter list may be omitted entirely:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably move this to the end of the section, just so things flow more naturally (discussion about parameters followed by an example of parameters instead of a discussion of parameters followed by an example of no parameters)

- `constexpr` - Explicitly specifies that a lambda's `operator()` is a
[constexpr function](https://en.cppreference.com/w/cpp/language/constexpr#constexpr_function).
- Mutually exclusive with `consteval`.
- Lambdas are implicitly marked `constexpr`, if possible.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be helpful to link to the criteria that determines if this is possible, either directly or as a footnote

Copy link
Member

@jeremy-rifkin jeremy-rifkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave the rest a read, just a couple comments

Comment on lines +185 to +188
- `static` - Makes a lambda's `operator()` a
[static member function](https://en.cppreference.com/w/cpp/language/static#Static_member_functions).
- Mutually exclusive with `mutable`.
- Cannot be used if the captures list is not empty, or an explicit `this` parameter is present.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be helpful to describe why this might be useful. Also it might be worth noting the lambda -> function pointer trick in some other section, and how this works even without static:

auto* ptr = +[]{ return 4; };

Lambdas may be given attributes that apply to their `operator()`s since C++23:
```cpp
auto very_important_number = [][[nodiscard]] { return 4; };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very minor style nit but I'd suggest putting a space between the attribute, and the capture block, otherwise it's just a big block of square brackets [][[

Suggested change
auto very_important_number = [][[nodiscard]] { return 4; };
auto very_important_number = [] [[nodiscard]] { return 4; };


 

### Capturing function parameters
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this section is way too niche :)

Comment on lines +297 to +300
Making a type alias with an in-line lambda in a header file or module interface violates the
[One-Definition Rule](https://en.cppreference.com/w/cpp/language/definition) because aliases are not a "definable item",
so lambdas in them are not allowed to match with other lambda declarations in other
[translation units](https://en.cppreference.com/w/cpp/language/translation_phases#Translation_process):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I can imagine problems here I'm not seeing why this is an ODR violation, because this isn't a definable https://eel.is/c++draft/basic.def.odr#15 doesn't apply. This is an ODR violation though: https://eel.is/c++draft/basic.def.odr#18.

 
### In-line partial specialization
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid I don't see why this is useful. It's also not really a specialization, which can be most clearly seen in the index sequence example. I would recommend keeping that example since that is a common useful pattern.

@jeremy-rifkin
Copy link
Member

Converting to draft until ready

@jeremy-rifkin jeremy-rifkin marked this pull request as draft July 12, 2025 20:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants