8

So I understand using var in C# makes sense because you have anonymous types that are compiler derived. C++ doesn't seem to have this feature (unless I'm wrong), so what is the point of having an auto keyword?

(It is kinda cool that unlike C#, auto does work for member/global variables, which is cool I guess, but doesn't seem enough to justify its existence).

Rapptz
  • 20,807
  • 5
  • 72
  • 86
sircodesalot
  • 11,231
  • 8
  • 50
  • 83
  • 1
    I wouldn't describe `var` using "anonymous types that are compiler derived" so much as eliminating redundant/painful* type declarations for the developer. *see LINQ EDIT: Oh wait, yeah, you can use it for the anonymous types. Disregard me. :) – Chris Sinclair Jul 17 '13 at 01:43
  • That's really the only time you *have* to use `var` though. You only need to use `var` in a LINQ expression when the result is anonymous. – sircodesalot Jul 17 '13 at 01:44
  • 8
    C++ lambdas are of anonymous types, much like C# lambdas. In that context, `auto` and `std::function` serve the same purpose as `var` and `Func` respectively. – Jon Purdy Jul 17 '13 at 01:51
  • `C++ lambdas are of anonymous types, much like C# lambdas.` That's a good point. I ran across that not too long ago. – sircodesalot Jul 17 '13 at 01:54
  • You don't need to have anonymous types to benefit from type inference. In fact, I'd consider a static type system with no inference to be incomplete at best. – Cat Plus Plus Jul 17 '13 at 01:57
  • In addition to lambdas, there other situations in which the data type is not explicitly specified by the Standard and hard or impossible to predict for the programmer. One example is the return type of [`std::bind`](http://en.cppreference.com/w/cpp/utility/functional/bind). – jogojapan Jul 17 '13 at 02:01
  • 4
    GCC and Clang have quite a bit better C++11 support than MSVC. – chris Jul 17 '13 at 02:07
  • ideone and stack crooked are both online compilers with more C++11 support than MSVC2012. – Yakk - Adam Nevraumont Jul 17 '13 at 02:19
  • You are wrong, C++ has anonymous types, both compiler and library-generated. auto can not be used for members. Stroustrup's book is full of terrible errors and CAN NOT BE TRUSTED. – robson3.14 Jul 17 '13 at 11:50
  • @robson3.14 : Can you prove that? – Pixelchemist Jul 17 '13 at 14:18
  • Even ignoring lambdas, C++ has anonymous types: `struct {} thing;` – Mike Seymour Jul 17 '13 at 16:06

8 Answers8

34

auto has a lot of uses when it comes down to both generic programming and to save the programmer some typing.

For example, consider this. Would you rather type out:

std::unique_ptr<name::long_type::goes_here> g = 
    std::make_unique<name::long_type::goes_here>(1,2,3,4)

or:

auto g = std::make_unique<name::long_type::goes_here>(1,2,3,4)

Yes, they're both long but we know the return type and specifying it again is a bit cumbersome to type. This also goes for iterators:

for(auto i = vec.begin(); ...)

vs:

for(std::vector<type>::iterator i = vev.begin(); ...)

Its use in generic programming is also to figure out the return type of a function or if you're doing some generic algorithms where you don't know the type.

For example, consider a very basic example.

template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
    return t + u;
}

This allows the compiler to figure out the type of the add operation rather than us trying to figure it out ourselves. Note that in C++14 you can omit the trailing return type. Its uses in generic programming don't stop there either. If we wanted to work with any type of container as a wrapper function for algorithms we could use auto to help us with it. For example:

template<class Cont>
void my_sort(Cont&& cont) {
    using std::begin;
    auto first = begin(std::forward<Cont>(cont));
    // work with the iterators here
}

In the future (C++14), auto can be used to make polymorphic lambdas as well such as:

[](auto a) { return a + 4; }

Which can be useful as well.

Rapptz
  • 20,807
  • 5
  • 72
  • 86
  • Rapptz, extracted the code to code blocks to make the differences more obvious. Hope you don't mind. Here's a +1 to compensate you if you do :-) Just kidding, the +1 is because it's a good answer. – paxdiablo Jul 17 '13 at 01:50
  • @paxdiablo Thanks! I wanted to do that too :) – Rapptz Jul 17 '13 at 01:51
  • Seriously, C++14 already. I was all excited that C++ went 'up to 11'. How am I ever going to keep up, heh. – sircodesalot Jul 17 '13 at 01:58
  • 2
    @sircodesalot C++14 is a "minor" release. Not as big as C++11 but brings in some very nice things to play like polymorphic lambdas, optional, omitting the trailing return type for functions and other interesting stuff. – Rapptz Jul 17 '13 at 02:03
  • On a related note. I just started downloading visual studio 2013 preview. That's insane. 2012 JUST came out. (Hopefully there is better C++11/14 support). – sircodesalot Jul 17 '13 at 02:12
  • 1
    @sircodesalot: "*I just started downloading visual studio 2013 preview. That's insane.*" How is that "insane"? It's a *yearly release* schedule. Firefox will have *eight releases* in a year, with Chrome having about that many as well. If anything, VS's release schedule is slow, compared to Clang (2 per year) and GCC. – Nicol Bolas Jul 17 '13 at 02:19
  • @NicolBolas I suppose a difference between them is they're all free while Visual Studio is proprietary. – Rapptz Jul 17 '13 at 02:23
  • 2
    @NicolBolas: difference beeing, that VS is quite expensive… – MFH Jul 17 '13 at 06:33
  • @sircodesalot `I just started downloading visual studio 2013 preview. That's insane. 2012 JUST came out.` You might as well say "I just looked at the calendar and it's 2013. That's insane. 2012 JUST ended." – Lightness Races in Orbit Oct 17 '13 at 13:05
15

There are a number of uses for auto in C++

  1. Anonymous function objects, aka closures, aka lambda instances. auto is the only way to store them. Types can also be generated derived off those types, and types on their backs, ad infinitum.

  2. C++ can have quite complex types, such as the type of a non mutating iterator into an unordered map that uses a custom allocator and hashing function. typedef can mitigate this, but the type of a m.begin() having a particular name is not that informative: foo_iterator it = is as meaningful as auto foo_iterator =, and the auto one does not require boilerplate elsewhere.

  3. Return type deduction uses the auto keyword, which is required to do some template functions work without huge amounts of traits boilerplate. Eliminating boilerplate is a common theme: C++s robust type system means that types can carry lots of information, and encoding it at every use can be counterproductive.

  4. In some ducktype template code, the work to deduce the type of a variable is roughly the same as the work to code the variables value, and nearly identical in structure, some times literally: decltype(long expression) x = long expression;. auto eliminates that duplication.

  5. Finally in C++1y, type deduction lambdas use auto to say that an argument is a deduced one. Sort of a light weight template. Talk to extend this to non lambdas is also in skunkworks.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • Since C++20, the `auto` keyword can also be used [as a function parameter type](https://stackoverflow.com/a/60355539/975097). – Anderson Green Sep 01 '21 at 14:17
5

HEre's a real life example where I could not, not use auto

I was trying to do a switch type statement in C++ where the return type is implementation specific and could not be declared easily. So using an 'auto' is probably the right way to resolve the type look up for the map declaration.

auto foo = boost::bind(&VegaFactory::load_commodity_one_leg,this,conn,_1);
std::map<std::string,decltype(foo)> methods;
methods.insert(std::make_pair("FOO",commodityOneLeg));

auto f = methods.find(bar);
// Call f here
Delta_Fore
  • 3,079
  • 4
  • 26
  • 46
  • This can use `std::function` instead of `auto`, so it's not quite impossible to not use `auto`... – rubenvb Oct 02 '13 at 14:02
3

C++ does have "anonymous" types - types you cannot refer to by name because the name is not available to you. This was the case even before C++11 and lambdas. Consider the following code:

class foo {
    class bar { 
      public:
        void baz() { }
    };
  public:        
    static bar func() { return bar(); }
};

foo::func().baz(); // OK, only the name "bar" is private
??? a = foo::func(); // Umm...
auto b = foo::func(); b.baz(); // Hooray!

Even if not actually declared in a private scope, it is often useful for a library to leave some types unspecified in its API - especially when heavily utilizing expression templates or other template metaprogramming where the type names can be arbitrarily long with all the nested template arguments. Even the standard itself does this - for instance, the result type of std::bind is not defined by the specification.

JohannesD
  • 13,802
  • 1
  • 38
  • 30
2

syntactic sugar

I rather say

auto i = mapping.begin();

over

std::map<int, int>::iterator i = mapping.begin();
masoud
  • 55,379
  • 16
  • 141
  • 208
andre
  • 7,018
  • 4
  • 43
  • 75
1

It is well worth reading Herb Sutter's article Almost Always Auto for some great examples of why it's worth using auto over explicit types. The main advantages are the reduction in typing, and gives additional safety if the underlying types change. One of my favourite examples though is about how it reduces duplication. If you allocate on the stack then you'd use:

MyClass c(param);

However, if you want to create on the heap you need:

MyClass* c=new MyClass(param);

So you've had to duplicate the MyClass, but the RHS already forces the variable to be a MyClass pointer, so you can just use this instead:

auto c=new MyClass(param);

If you want to declare it as a unique_ptr then previously you would need:

unique_ptr<MyClass> c=make_unique<MyClass>(param);

which can be abbreviated to:

auto c=make_unique<MyClass>(param);
the_mandrill
  • 29,792
  • 6
  • 64
  • 93
1

In C++, auto keyword provides a way of type deduction mechanism. For example,

   auto i = expressions;

auto keyword tells the compiler to determine the type of variable i from the expression on the right side of the assignment operator.

Therefore if the value of expressions is double, then variable i will be double. Or, if the value of expressions is bool, then variable i will be bool.

aliceangel
  • 304
  • 1
  • 5
  • 19
0

so, let's learn type inference first which is basically refers to automatic deduction of the data type of an expression in a programming language.

before C++ 11 all the variables in c++ have to explicitly declare but after the release of c++ 11, the compiler itself deduces the type of the variable at runtime.

we can use it for variables and even in the case of function return types. but, it's suggested to avoid using auto in function return type.

shaw_7
  • 29
  • 6
  • That's incorrect. The compiler deduces nothing at run time, it can't possibly do that, since the compiler isn't running by the time you are able to run the produced executable. The compiler only runs at compile time, and the type of the variable is deduced at compile time. – Elijan9 Apr 22 '20 at 09:48