C++ Weekly - Ep 288 - Quick Perf Tip: Prefer `auto`

preview_player
Показать описание


☟☟ Awesome T-Shirts! Sponsors! Books! ☟☟

Upcoming Workshop: C++ Best Practices, NDC TechTown, Sept 9-10, 2024
Upcoming Workshop: Applied constexpr: The Power of Compile-Time Resources, C++ Under The Sea, October 10, 2024

T-SHIRTS AVAILABLE!

WANT MORE JASON?

SUPPORT THE CHANNEL

GET INVOLVED

JASON'S BOOKS

► C++23 Best Practices

► C++ Best Practices

JASON'S PUZZLE BOOKS

► Object Lifetime Puzzlers Book 1

► Object Lifetime Puzzlers Book 2

► Object Lifetime Puzzlers Book 3

► Copy and Reference Puzzlers Book 1

► Copy and Reference Puzzlers Book 2

► Copy and Reference Puzzlers Book 3

► OpCode Puzzlers Book 1


RECOMMENDED BOOKS

AWESOME PROJECTS

O'Reilly VIDEOS

Рекомендации по теме
Комментарии
Автор

I used to be against auto (and var in C#) because I thought it was lazy and too unspecific, but in the past half decade or so I've come to think that auto (and var) is absolutely the correct way to go - the type of an expression should be determined by what's on the right side of an equation. You shouldn't have to specify two types that can get out of sync and make refactoring a nightmare (or more than a nightmare than it has to be).

Someone also mentioned attempting to get around an imposition of auto, or at least as an aide-a-reader, by using Hungarian notation. As far as I'm concerned that's also part of the problem. Variable names should be descriptive, but should not be a strained attempt to incorporate what the author believed a type to be at the time of writing.

And the kicker: if Bjarne thought this was the way to go back in 1985 or so, then it's the way to go! The man knew/knows what he's doing.

treyquattro
Автор

If you decide to use more `auto`, consider using `const auto`, the way you (probably) use `const char *'. It helps with const correctness.

davidkatz
Автор

`auto main() -> int {}`
That's how I write the main function :| you're preaching to the choir 😄

LemonChieff
Автор

I recently read one of Scott Mayer's book and he also mentioned this detail in the book. Except for some intermediate classes, auto works properly for all the other cases. One of the exceptions is very famous std::vector<bool>::iterator.

hanyanglee
Автор

since I learned c++ mostly by myself after having c classes at university, nobody ever told me what is considered "good" or "bad" habit. So I used auto for non-default construced objects (like smart pointers) since day 1, because most of the time you have the exact type in the right hand of the variable definition. And it's very usefull to use auto as the return type of templated function or method, because you don't always know the type, but the compiler will know.

Raspredval
Автор

Great ! Also a very good alternative to `typedef' and `using` directive when our data type is cumbersome.

ali_youtube_user_
Автор

Consider putting a link to the past episode in the description if you send viewers to watch it before this one.

eboyarski
Автор

auto is nice to replace a whole lot of typing in the case of iterators and such, but when it deduces to a basic type I would rather be explicit. Too much auto in the code makes it difficult to read since you can't tell at a glance what type a variable is.

KillerMZE
Автор

I am wondering if pair implicit const convertion could just be returning a view (if convertion to ref) by using reinterpret cast. Because between pair<int, int> and pair<const int, int> the memory layout will not change. So we could implement the convertion by testing if the decayed type match and if and only we are adding a const to one or both of the element (easy to with is_const).
And we could be in the case of a function asking for a pair<const, non_const>& that only want to modify the value but we have an instance of pair<non_const, non_const>.

Arwahanoth
Автор

Yeah, I was definitely in the camp of - don't use 'auto', you don't know what you're getting, its not as clear, etc... But this was before I knew how auto really worked... turns out its the exact opposite (some times), you DO know exactly what you are getting (provided you know the rules of auto, which are simple really), without auto you only "think" you know :p - I was 80% convinced before this vid, I am now 99% convinced - thanks : )

alastair
Автор

What are your thoughts on auto vs. auto &&? The latter will never perform an accidental copy.

rwllnkw
Автор

I recently encountered a class of situations where auto can improve compile times (there are alternatives but auto is the most sensible solution). For context, I was writing an aggregate tuple implementation with a focus on improving compile time over std::tuple in cases where a very wide tuple is created by concatenating many small tuples, two at a time (with associativity as if concatenating with operator+). For reference, concatenating 150 small std::tuples in this way on my implementation and machine takes just over 5 minutes to compile.

To understand where auto fits in this problem, one needs some familiarity with the template argument deduction process and overload resolution. In particular, one needs to know that substitution occurs in lexical order and in multiple phases, and that constraints are checked after a complete template argument list is available (assuming DR2369), as well as the fact that during overload resolution, function templates contribute synthesized declarations (not definitions) to the candidate set. What that means is that, depending on how you form your function templates, costly substitutions may take place during deduction before your constraints are checked (although with SFINAE-based forms, you have far more control), so the compiler may waste time substituting into a template that never contributes to the candidate set or candidates that are never selected.

My tuple implementation initially had just one generic tuple_cat form that flattened any number of tuple-like objects into my own tuple type, but whose return type involved quite a bit of computation. I saw an opportunity here to optimize for my target case; I would create a specialization that handles the concatenation of two tuple-like objects, which is a much simpler problem to solve for. I implemented it and...
a slight regression in the number of template instantiations, because the compiler was still performing template instantiations in the return type of the generic overload even though my test case never called on it. With DR2369, this issue can be resolved using C++20 constraints or (barring C++20 or DR2369) with some application of SFINAE, but in this situation neither solution contributes to program correctness and are detrimental to documentation as they expose implementation details that are irrelevant to the purpose or use of the functions.

Here is where auto comes in.
Note that auto foo(); is a valid function declaration - NOT an abbreviated function template declaration. For this reason, function templates whose return types are deduced from the body do not require the instantiation of the function template in order to synthesize the declaration that is added to the candidate set for overload resolution. If such an instantiation occurs, it only occurs for the most viable candidate, if that candidate was produced by a function template.

By changing the return type of my overloads to auto and offloading the computation of the return type to the function template bodies, I avoid much of the overhead of the unused, generic overload. For the same case that took std::tuple over 5 minutes to compile, my implementation ended up taking under four seconds (and if i recall correctly, down from about 30 seconds with the generic form).

iuploadthereforeiam
Автор

All of these issues should be highlighted in the IDE. If have written a line that is resulting in conversions and/or copies, the IDE should show a 'conversion' or 'copies' squiggly for that code.

msew
Автор

I'm sold. I agree about concerns with readable code. But that can be delt with a coding convention / standard and code reviews. If you don't do code reviews you don't get to moan about auto. 😁

RichardEricCollins
Автор

The only place I can think of where auto would do an accidental conversion is in `int arr[] = {1, 2, 3}; auto x = arr;`. From a novice's point of view, they might expect a copy of the array here, but they'll get a pointer instead (obtained through an array-to-pointer conversion). It's quite common IME for newcomers to expect arrays to allow things like copy and assignment.

In any case, this doesn't ruin your point at all.

Qazqi
Автор

I feel like "auto" has improved the readability of my code. Not only because it contains less noise, but mainly because I put type information into my variable names. Before auto, I thought this was useless redundancy. Now I evolved in doing so just because I almost always use auto.

AlfW
Автор

"You are wrong there"

(Now you don't have to wait anymore, enjoy your day)

Anyhow, I saw Scott Meyer's talk of type deduction cppcon 2014 after part 1 and that was a really good source! Has much changed in c++17 and 20?

jhbonarius
Автор

Love it. Great explanation and observation of the compiler having always known the correct type anyway.

Curiously, most of the complaints about auto have been about reading the code. I have never really understood this stance, but it keeps coming up. Function and variable naming would be my answer, and that's where these small examples often fall down. get_data really isn't saying much here. Perhaps properly named examples, rather than generic naming would help, somehow?

razu
Автор

I was having a "heated" argument with one of my coworkers about using auto in code instead of explicitly writing every type.

I didn't push enough the point of possible conversations.
Our code has many legacy lines where it was written originally long ago and it's not very standard, sometimes an int is used, sometimes custom type or 3rd party type.
Which causes lots of unintended conversions.

TNothingFree
Автор

A rule I've been following is to use auto by default unless the type is not obvious from the right hand side of the assignment. In that case, readability is almost always more important. If not, then during profiling your code should turn out to be on the hot path and you can clarify your confusing use of auto with a comment.
If you're using a custom type, that comment will grow stale over time but if you have a decent IDE like Visual Studio, it will detect your use of the type name in the comment and whenever you change the type name, it will suggest changing it as well.

peterbonnema