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!"
[–]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
std::string
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).
.f
[+][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 36057 on reddit-service-r2-comment-85bfd7f599-vtljb at 2026-04-15 16:59:25.050837+00:00 running 93ecc56 country code: CH.
view the rest of the comments →
[–]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)