39

I'm learning C++ now because I need to write some low level programs.

When I learned about auto keyword, it reminds me of the var keyword from C#.

So, what are the differences of C# var and C++ auto?

Julian
  • 5,290
  • 1
  • 17
  • 40
Kangjun Heo
  • 1,023
  • 1
  • 8
  • 19

3 Answers3

41

In C# var keyword works only locally inside function:

var i = 10; // implicitly typed 

In C++ auto keyword can deduce type not only in variables, but also in functions and templates:

auto i = 10;

auto foo() { //deduced to be int
    return 5;
}

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

From performance point of view, auto keyword in C++ does not affect runtime performance. And var keyword does not affect runtime performance as well.

Another difference can be in intellisense support in IDE. Var keyword in C# can be easily deduced and you will see the type with a mouse over. With auto keyword in C++ it might be more complicated, it depends on IDE and tooling.

Tomas Kubes
  • 23,880
  • 18
  • 111
  • 148
  • Then, auto can be used wider scopes? – Kangjun Heo Nov 24 '16 at 09:07
  • Yes, with auto in C++, you can build entire chains of deduction with strong type checking. – Tomas Kubes Nov 24 '16 at 09:09
  • `var` doesn't affect performance in C#, the example you linked to is broken, as `List bar1 = Foo();` produces a compile-time error. See [Servy's comment](http://stackoverflow.com/questions/356846/will-using-var-affect-performance?rq=1#comment68562462_356855) – Lucas Trzesniewski Nov 24 '16 at 09:18
  • How come it doesn't affect performance though? I must take some CPU time to determine the type of the variable right? Or is it determined during compilation? An as a follow up, why don't we only use auto? – Boyan Kushlev Mar 19 '17 at 13:58
  • 1
    yes, the deduction is made during compilation time, that is why performance is not changed. I don't use auto/var too much, because I like to see the types without point by mouse over every variable in code. but if the type is very complicated, I am lazy to write it and I use auto/var. – Tomas Kubes May 29 '17 at 05:51
  • I think a general good rule of thumb for when to use auto/var is if the type is obvious from the name or context and/or the variable type is excessively lengthy. I've seen some nested template iterators that were over a hundred characters long, it's scary stuff! – Nemo Aug 27 '19 at 21:19
15

To put things simply, auto is a much more complicated beast than var.

First, auto may only be part of the deduced type; for example:

std::vector<X> xs;
// Fill xs
for (auto x : xs) x.modify(); // modifies the local copy of object contained in xs
for (auto& x : xs) x.modify(); // modifies the object contained in xs
for (auto const& x : xs) x.modify(); // Error: x is const ref

Second, auto may be used to declare multiple objects at once:

int f();
int* g();
auto i = f(), *pi = g();

Third, auto is used as part of the trailing return type syntax in function declarations:

template <class T, class U>
auto add(T t, U u) -> decltype(t + u);

It may also be used for type deduction in function definitions:

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

Fourth, in the future it may start to be used to declare function templates:

void f(auto (auto::*mf)(auto));
// Same as:
template<typename T, typename U, typename V> void f(T (U::*mf)(V));
ach
  • 2,314
  • 1
  • 13
  • 23
  • This should have been the accepted answer and even it misses some uses. 1 - `auto&&` is the only other place which uses universal references. 2 - `auto` can be used in lambda expression parameters. And I am guessing even I am missing some usages. – Tanveer Badar Aug 17 '20 at 06:59
6

They are equivalent. They both allow you not to specify the type of a variable yourself, but the variable stays strongly-typed. The following lines are equivalent in c#:

var i = 10; // implicitly typed  
int i = 10; //explicitly typed  

And the following lines are equivalent in c++:

auto i = 10;
int i = 10;

However, you should keep in mind that in c++ the correct type of an auto variable is determined using the rules of template argument deduction for a function call.

SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
  • 1
    Plus one. Note that in certain instances in C++, the use of `auto` is unavoidable - such as when you're working with lambda functions. Is that also true in C#? Also note `auto i = 10;` has *very* different meaning pre and post C++11 (even though in this particular case both standard set `i` to an `int` type). – Bathsheba Nov 24 '16 at 08:45
  • Why unavoidable? `auto` *does* resolve to a concrete or generic type at compile time. You can replace it with that concrete type – Panagiotis Kanavos Nov 24 '16 at 08:47
  • And the concrete type for a lambda function is? – Bathsheba Nov 24 '16 at 08:47
  • The one determined by compiler resolution. what is the item type of a `vector` ? – Panagiotis Kanavos Nov 24 '16 at 08:49
  • 1
    @Bathsheba You actually *can't* use `var` in C# for implicitly-typed lambdas. You have to use an appropriate delegate type (which could be an `Action<>` or a `Func<>`). So actually, `var` and `auto` are NOT equivalent, at least as far as lambdas are concerned. – Matthew Watson Nov 24 '16 at 08:51
  • @PanagiotisKanavos - according to the spec, "The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed nonunion class type". The _unnamed_ part means `auto` is unavoidable. – Allison Lock Nov 24 '16 at 09:15
  • @Bathsheba in C# you can only use `var` when handling anonymous types (obviously) like `var foo = new { bar = 42 };`. `var` with a lambda would be ambiguous: C# lambdas can either become a callable like in C++ (`Func<...>`), or an expression tree (`Expression>`), and in both cases `var` can't assign a type to them. – Lucas Trzesniewski Nov 24 '16 at 09:15
  • @PanagiotisKanavos Every lambda function has a unique type, so you cannot get the type of lambda function and then assign it afterwards. In `decltype( [...](...) {...} ) = [...](...) {...}`, both lambda functions can have different types. You can assign the lambda function to an auto variable and then get the type, or you can use lambdas as template arguments where don't need auto. – Jens Nov 24 '16 at 11:25
  • @Bathsheba `var` is used almost always when defining data returned from a LINQ query. – Aykhan Hagverdili Jul 14 '19 at 19:12