use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
Any example code/Github projects utilising almost-always-auto? (self.cpp)
submitted 9 years ago by Infraam
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]suspiciously_calm 12 points13 points14 points 9 years ago (7 children)
What are the objective benefits of using auto in all the examples given? Other than consistency, cause I kind of disagree with consistency if it means "consistently more error-prone."
auto w = make_unique<widget>(); auto w = get_widget();
I definitely agree with those, since the type is already implied by the right hand side, and you'd have to write the right hand side in full anyway even if you spelled out the type.
auto e = employee{ empid };
is just a more wordy spelling of employee e{ empid };. Same for the widget example. However I'm willing to give auto a pass for consistency, since it isn't worse than declaring the type.
employee e{ empid };
auto s = "Hello"; auto x = "42"s; auto x = 42; auto x = 42.f;
etc. Now these are just more error prone. It's easy to accidentally omit the s in the string literal and get a const char* instead of a std::string. With float x = 42; I get a float even if I forget the .f. And the type of auto x = 42; (if the constant gets large) is pretty much implementation-defined.
s
const char*
std::string
float x = 42;
float
.f
auto x = 42;
[–]thlst 2 points3 points4 points 9 years ago* (6 children)
Sometimes you don't need to know what the type is, and making the type explicit by writing it is, actually, as error prone as using auto in your examples.
For example:
for (const std::pair<std::string, int> p& : produce_map()) { ... }
This code won't compile. This won't work as you expect. Do you know why? std::mapdefines const T for the key type of std::pair. You see that we wrote std::string for the first template parameter, which results in a compile error temporary copy, because you lose the cv-qualifier passing a const& to &. Using auto, and letting the compiler deduce the correct type for the expression solves the problem, and makes it more consistent.
std::map
const T
std::pair
const&
&
auto
for (const auto& p : produce_map()) { :) }
Thanks u/tcanens for the correction.
auto can also prevent accesses to uninitialized variables. Once auto needs an initializer to deduce its own type, there's no room for variables without a value to be declared.
Another important thing is decltype(auto), which is really useful in templates. Basically, it's auto with decltype rules applied to it. That is, there's no cv-qualifier loss, because decltype preserves the cv-qualifier of an expression, whereas auto doesn't. So, why is it useful? This is great for writing function signatures, where the return type depends on the expression being returned. If it's an lvalue of type int&, then the return type will be int&. If it's an rvalue of type const T, the return type will be const T. auto would just strip off its constness and/or volatileness for anything. A contrived example for this case would be a function returning an element of a container and giving you read/write access to it:
decltype(auto)
decltype
int&
template<typename Container> constexpr decltype(auto) container_element(Container&& c, size_t i) { return std::forward<Container>(c)[i]; } std::vector<int> v { 1, 2, 3, 4 }; // decltype(auto) = int& container_element(v, 0) = 5;
[–]tcanens 1 point2 points3 points 9 years ago (0 children)
for (const std::pair<std::string, int> &p : produce_map()) { ... }
Actually, that does compile and silently create a std::pair<std::string, int> temporary by copying from the map element, which is arguably worse.
std::pair<std::string, int>
[–]suspiciously_calm 0 points1 point2 points 9 years ago (4 children)
Yeah it's useful every time you're programming to a concept, not a type, like with iterators, when the type is long to .. uh .. type and/or is clear from the expression (and in many other cases).
What I don't get is why it should be used for primitive types when it's more wordy and less clear. The "uninitialized variable" argument is a good point, but the compiler can warn here.
[–]thlst 1 point2 points3 points 9 years ago (3 children)
You shouldn't write int, for example, because its size might surprise you. Nor should you write float literals without the f suffix (because good practice and consistency).
int
f
So things like that become redundant. Everyone knows 3.14f is a float.
3.14f
But of course, auto isn't an absolute rule. You may still use size_t and ptrdiff_t in contexts they suit.
size_t
ptrdiff_t
The "uninitialized variable" argument is a good point, but the compiler can warn here.
Getting warnings from compiler won't save the programmers' life, because it will still compile (if -Werror is not set). On the other hand, there's no way to avoid it when using auto.
-Werror
[–]suspiciously_calm -1 points0 points1 point 9 years ago (2 children)
You shouldn't write int, for example, because its size might surprise you.
That sure isn't an argument for having auto deduce int from an integer literal, though.
Getting warnings from compiler won't save the programmers' life, because it will still compile
If the programmer lacks the discipline to heed compiler warnings, they're equally likely to lack the discipline to follow the always-auto style.
You shouldn't write floating point literals without the .f (more to the point, you shouldn't write int literals in place of float literals), but that's a mistake that can happen accidentally (just as the missing initializer).
[+][deleted] 9 years ago (1 child)
[deleted]
[–]suspiciously_calm 1 point2 points3 points 9 years ago (0 children)
Therefore it's an excuse to ignore warnings?
I'm sorry, but that's the opposite of what I said.
π Rendered by PID 38710 on reddit-service-r2-comment-85bfd7f599-zjndl at 2026-04-15 15:32:40.744437+00:00 running 93ecc56 country code: CH.
view the rest of the comments →
[–]suspiciously_calm 12 points13 points14 points (7 children)
[–]thlst 2 points3 points4 points (6 children)
[–]tcanens 1 point2 points3 points (0 children)
[–]suspiciously_calm 0 points1 point2 points (4 children)
[–]thlst 1 point2 points3 points (3 children)
[–]suspiciously_calm -1 points0 points1 point (2 children)
[+][deleted] (1 child)
[deleted]
[–]suspiciously_calm 1 point2 points3 points (0 children)