The motivations in C++ are more extreme, as types can become vastly more convoluted and complex than C# types due to metaprogramming and other things. auto
is faster to write and read and more flexible/maintainable than an explicit type. I mean, do you want to start typing
boost::multi_map<NodeType, indexed_by<ordered_unique<identity<NodeType>>, hashed_non_unique<identity<NodeType>, custom_hasher>>::iterator_type<0> it
That's not even the full type. I missed off a couple template arguments.
Move semantics introduce a whole dimension to C++ - it isn't just there to let you return values cheaply.
For example, without move-semantics std::unique_ptr
doesn't work - look at std::auto_ptr
, which was deprecated with the introduction of move-semantics and removed in C++17. Moving a resource is vastly different from copying it. It allows transfer of ownership of a unique item.
For example, let's not look at std::unique_ptr
, since it is fairly well discussed. Let's look at, say, a Vertex Buffer Object in OpenGL. A vertex buffer represents memory on the GPU - it needs to be allocated and deallocated using special functions, possibly having tight constraints on how long it can live. It is also important that only one owner use it.
class vertex_buffer_object
{
vertex_buffer_object(size_t size)
{
this->vbo_handle = create_buffer(..., size);
}
~vertex_buffer_object()
{
release_buffer(vbo_handle);
}
};
void create_and_use()
{
vertex_buffer_object vbo = vertex_buffer_object(SIZE);
do_init(vbo); //send reference, do not transfer ownership
renderer.add(std::move(vbo)); //transfer ownership to renderer
}
Now, this could be done with a std::shared_ptr
- but this resource is not to be shared. This makes it confusing to use a shared pointer. You could use std::unique_ptr
, but that still requires move semantics.
Obviously, I haven't implemented a move constructor, but you get the idea.
The relevant thing here is that some resources aren't copyable. You can pass around pointers instead of moving, but unless you use unique_ptr, there is the issue of ownership. It is worthwhile to be as clear as possible as to what the intent of the code is, so a move-constructor is probably the best approach.
Best Answer
Almost every word you might think of adding as a keyword to a language has almost certainly been used as a variable name or some other part of working code. This code would be broken if you made that word a keyword.
The incredibly lucky thing about
auto
is that it already was a keyword, so people didn't have variables with that name, but nobody used it, because it was the default. Why type:when
meant exactly the same thing?
I suppose somewhere on the planet there was some small amount of code that used 'auto' the old way. But it could be fixed by removing the 'auto' and it would be working again. So it was a pretty obvious choice to repurpose the keyword.
I also happen to think it's a clearer meaning. If you've worked with variants and such, when you see
var
you may think that the declaration is somehow less strongly typed than if you pressed all the keys yourself on the keyboard to specify the type of the variable. To me,auto
makes it clearer that you're asking the compiler to automatically deduce the type, which is just as strong as if you had specified it yourself. So it really was a very lucky break that made a good name available to the committee.To clarify the (small) breaking:
If you had
and tried to compile with a C++ 11 compiler, you will now get an error such as
This is trivial, you just remove either the auto or the int and recompile.
There is a bigger problem though. If you had
C and the really old C++ would make
i
anint
(as it would if you left offauto
- default declaration wasint
). If you have gone a really long time without compiling this code, or have been using old compilers, you could have some of this code, at least in theory. C++ 11 would make it adouble
since that's what 4.3 is. (Or maybe afloat
, I'm still in Boxing Day mode, but the point is, not anint
.) This might introduce subtle bugs throughout your app. And without any warnings or errors from the compiler. People in this boat should search globablly forauto
to make sure they weren't using it the old way before they move to a C++ 11 compiler. Luckily, such code is extremely rare.