When I first read about the new "datatype" auto in C++11 I was like WHAT??? You kidding, right???
Does any serious programmer use this keyword?
I mean: for(auto i=0; i<foo; ++i) is obvious.
But: auto x = y; is totally stupid.
Not only is it ambiguous, I also have to look up the type of 'y' to know what type 'x' is.
And, whenever I change the type of 'y', the type of 'x' changes too. So I have to search all my code for the use of 'y' to make sure that none of the automatic type changes causes no errors.
Looks to me like a method that would appeal to a theoretical computer scientist, but in a production environment ... well, I think it's dangerous.
Sometimes it's a good thing that the type of x changes when the type of y changes because otherwise you might forget to change x when you change type of y.
It can also save some typing, for instance when iterating using iterators. I don't really care if it's a std::vector<int>::iterator, all I care about is that it is an iterator over some container so using auto doesn't really make the code harder to read. It can even make it easier to read because you get rid of all that wordy stuff.
For example: for (std::unordered_map<std::chrono::steady_clock::time_point, std::vector<std::pair<std::string, int>>>::const_iterator i = schedule.cbegin(); i != schedule.cend(); ++i)
and for(auto i = schedule.cbegin(); i != schedule.cend(); ++i)
or auto z = [](const std::unordered_set<std::string>& x, double y){return app::map(x, y);}
Try to write resulting type of z yourself
Not only is it ambiguous, I also have to look up the type of 'y' to know what type 'x' is.
Sometimes you do not need to know type of variable to correctly use it.
And, whenever I change the type of 'y', the type of 'x' changes too.
So you do not have to look through your code to change everything accordingly.
Use auto responsible and you will not run into errors. Use it everywhere and sometime you will run into problems.
There is some cases when you have to use auto and trailing return type. To return private innner types:
1 2 3 4 5 6 7 8 9 10
class Test
{
private:
typedefint tst;
public:
tst foo();
};
auto Test::foo() -> tst
{return 0;}
i feel its an awesome feature, with these features c++ has reinvented itself, it would have been better if they would have introduced a GC to take care of memory!!
Also auto is extremely useful to further enhance duck typing of templates.
For example: we created new "data type" or something like Constraint from C++14. It have member function data() which will return reference to underlying data structure. Said structure is implementation defined, but should satisfy requirements of standard Container.
1 2 3 4 5 6 7 8
template<class T>
size_t foo(const T& myClass)
{
auto u = myClass.data(); //What to write if not auto?
for(auto i = u.cbegin(); i != u.cend(); ++i) {
//Do something
}
}
Because you don't know the type of 'y' and/or 'x'.
MiiNiPaa: For example: for (std::unordered_map<std::chrono::steady_clock::time_point, std::vector<std::pair<std::string, int>>>::const_iterator i = schedule.cbegin(); i != schedule.cend(); ++i)
That's exactly what I mean with "dangerous". If you need constructs like this it's maybe better to redesign your data structures instead of "auto" away that monster. Or at least typedef this into something meaningful.
anirudh sn: ... it would have been better if they would have introduced a GC to take care of memory!!
What dangerous in it? You know that .cbegin() member function returns at least ForwardIterator, which cn be incremented, dereferenced and checked for unequality. Why would you need to know full type?
Actually, what would MyMap::const_iterator tell you if I have used typedefs. How is it safer?
MiiNiPaa's example has simple tabular data. One could invent a meaningful typedef name, but Schedule::const_iterator i = schedule.cbegin() has redundancy.
plexus wrote:
Because you don't know the type of 'y' and/or 'x'.
You do know, however, that 'x' and 'y' do have same type. That is a nice guarantee.
If they should not have same type, then you will write explicit type.
Whether you do use explicit type written out, or a typedef, you have to consult the declaration of 'y'/typedef to make sure that you don't introduce accidental type conversion.
> But: auto x = y; is totally stupid.
> Not only is it ambiguous, I also have to look up the type of 'y' to know what type 'x' is.
In isolation, auto x = y; is neither stupid nor smart.
Writing auto x = y; is smart, if all that one needs to specify and know is that x and y are of the same type; if when the type of x changes, the type of y must change too.
Writing auto x = y; is stupid, if there is a genuine need to specify or know the precise type of x; when under certain situations, type of x must be different from the type of y.
I mean this more in a general way. I have to maintain a lot of programs that were written, changed, extended, ported and changed again by a multitude of programmers over the course of 10 to 15 years.
And it's lines like that that cause the most errors and strange effects, because the people didn't quite understand what was going on there.
Of course, one could say: "Bad example, because a programmer has to know what he's doing" and that's right. But unfortunately, in the real world many programmers don't. Or they are forced to work on the code without having any time to get familiar with it.
So, avoiding things like that in the first place, and using types and names that make sense right away improves programs a lot, for programmers and users.
Yes, that. Also, to write easily understandable, portable and maintainable code. For instance,
1 2 3 4 5 6 7
// type of i is: the most efficient integral type large enough to hold the value
auto i = 12345678912345 ;
// type of j: integral type capable of holding upto 16 decimal digits
decltype(9999999999999999) j = 0 ;
auto k = i ; // k is of the same type as i