7 ms·
This a matter of debate in the C++ community. The “almost always auto” camp has the position that it makes the code more flexible and easier to refactor. The
by Game_Ender 8y ago
This a matter of debate in the C++ community. The “almost always auto” camp has the position that it makes the code more flexible and easier to refactor. The fewer times you write a type name the easier it is to change. It also has its uses in template heavy code which is popular on modern C++.
There is a group such as your self that value the extra context the type provides. I think the counter to is that modern tooling can provide this information to you. To split the difference you can use auto just where the type is redundant, like with make_shared, or verbose and unneeded, like with iterators.
- mlthoughts2018 8y agoIt might be easier to change types behind the scenes when using auto, but why would someone feel that is going to be a common case? When are you completely changing types all the time? More often, the types don’t change all that much, but their behaviors get extended and new features have to be calculated in some block of code. If you can see the type explicitly, then you know what operations it supports, etc. If I come across a structured binding where x and y are auto assigned as the unpacking of struct fields whose types might be complicated, now I have local variables x and y that I cannot reason about until I backtrack manually to figure out what type they will be deduced to having (and then keep that in memory any time I’m tinkering in that section of code). I guess for the cases when big structural overhauls are happening behind the scenes to radically change underlying types and designs, auto would reduce a bunch of rework on type annotations. However, I just can’t believe anyone would allow that to be a common enough use case for it to matter more than explicit type annotations.
- susam 8y ago> If I come across a structured binding where x and y are auto assigned as the unpacking of struct fields whose types might be complicated, now I have local variables x and y that I cannot reason about ... One is free to not use the auto keyword in a scenario like you mention in order to make the types explicit regardless of what the "Almost Always Auto" camp says. However there are scenarios where leaving the type out does not degrade readability and sometimes improves readability. Often cited examples of situations where it may improve readability usually look somewhat like this: void print_vector_of_maps(std::vector<std::map<std::string, std::string>> v) { for (const std::map<std::string, std::string>& item: v) { for (const std::pair<std::string, std::string>& entry: item) { std::cout << entry.first << ": " << entry.second << '\n'; } std::cout << "---\n"; } } With the auto keyword, it looks like this: void print_vector_of_maps(std::vector<std::map<std::string, std::string>> v) { for (const auto& item: v) { for (const auto& entry: item) { std::cout << entry.first << ": " << entry.second << '\n'; } std::cout << "---\n"; } } The types are still known from the surrounding context and the readability has arguably improved.
- mlthoughts2018 8y agoThe auto example here looks strictly worse than just creating a descriptive typedef/typename to shorten the syntax of the first approach. I’m all for shorter syntax, just not at the expense of completely explicit type annotation.
- xyrouter 8y agoThe usage of the word "strictly" here is strictly sloppy. Why is a typedef/typename better than using auto in this case? You can literally look up the actual type the auto keyword is deducing by looking at the function parameters two lines above. How many new typedefs do you want to create for code like this? You are suggesting creating two typedefs for this tiny 4-line code only. Imagine how many typedefs you might need to create in a real and complex project. How is the mess of typedefs going to be any more maintainable than this? There are places where the auto keyword would make it hard to understand the type and there are places where it won't. This is a place where the auto keyword does not make it hard to understand the type. Don't use the auto keyword if you don't want to but pretending that there is no value in using the auto keyword by using weasel words such as "strictly" is disingenuous.
- mlthoughts2018 8y ago> “Why is a typedef/typename better than using auto in this case? You can literally look up the actual type the auto keyword is deducing by looking at the function parameters two lines above.” Because a typedef makes the syntax equally as short as auto in all practical senses, while keeping the item type explicit. Even when figuring out the item type only requires looking up a few lines, this limitation of auto is still worse while not providing any “terseness” advantage. And obviously ising auto as a kludge for a type of polynorphism where you switch around header files, etc., to arrange the upstream type to change and rely on other code’s use of auto to “just work” is a severe and critically flawed kind of anti-pattern. In most cases it won’t be anywhere near this easy anyway, the the type of the function parameter should already have had an application-specific typedef to understand its meaning, so the extra use in places where auto is used would amortize it further. And since you get much more benefit from the typedef way in more complex situations, it would be better style to just use it consistently by using it in simpler situationd too, especially since when the situation is simple, like this example, auto by definition doesn’t provide an advantage. This is why I specifically used the word “strictly” like the mathematical sense of strictly increasing or a dominated function. The typedef approach for this is superior unilaterally.
- jcelerier 8y ago> When are you completely changing types all the time? I do, often enough (multiple times per month at least) that I have headers of typedefs for the alternative types that I have to use and which provide different performance characteristics and behaviours.
- mlthoughts2018 8y agoIn that case, it sounds like very bad general software design that is not well-crafted to the problems you are solving. Instead of building the right kind of extensibility in light of actual requirements that have self-evidently required you to change underlying types a lot, you are misusing something like auto to instead paper over a bad design. Needing to constantly switch things by creating different sets of headers with different groups of typedefs, and then rely on the codebase to have happened to use auto in just the right ways that things still compile correctly with the swapped-in types is horrible. Like, absolutely amateur, risk of getting fired level of badness. I can scarcely think of a way to design system-level polymorphism that would be more directly hostile to new developers or other people maintaining your code than the approach you’re describing. This sounds like the type of pathology when a developer creates a needlessly complex system purely for rent-seeking and job security. You’ve built a system nobody else can maintain because ever so slight changes to the way it uses auto can bring down the whole house of cards from your variety of special header files. Nobody else wants to catch that falling sword, so when they have to work on or change that code, they just tiptoe on eggshells to mimic whatever existing use of auto there is, out of complete fear that more specific type annotation is going to break things. This is not a hallmark of a good project. More like painting everyone else into a corner that only you happen to prefer.
- xyrouter 8y ago> In that case, it sounds like very bad general software design that is not well-crafted to the problems you are solving. That does not sound like bad software to me at all. It is quite a stretch to say that types changing during the course of software development implies the software is badly designed. This sound very backwards. On the other hand, I believe a software that is malleable enough to handle changing types easily during the course of software development is good software.
- fpoling 8y agoWhile modern tooling is helpful when coding, doing review or even just casual reading of the code with heavy use of auto is awkward especially for parts one has not worked recently. The tooling just not there at all. Sometimes the only choice is to apply the patch and check the code in IDE. Haskell and even Rust is less problematic in that area as Haskell does not have all those & const specifiers with complex rules of type deduction. And with Rust it is easy to see if a typeless let introduces a reference or copy or move.
- jcelerier 8y ago> The tooling just not there at all. how so ? most IDEs are able to tell you what type is behind your auto by a hover.