C#中的"var"和C++中的"auto"之间的区别

40

我现在正在学习C++,因为我需要编写一些低级程序。

当我了解到auto关键字时,它让我想起了C#中的var关键字。

那么,C#的var和C++的auto有哪些区别呢?


因为它们本质上是相同的,所以它们都用于类型推断。 - UnholySheep
那么,它们在技术上是相同的吗? - Kangjun Heo
基本上,您不能在匿名 lambda 中使用 var - Matthew Watson
这个问题是有效的。只需记住C++是一种高级语言,您应该像对待高级语言一样对待它。编写“低级”C++通常会导致糟糕的C++程序。 - David Haim
啊,我有点困惑“低级”和“本机二进制文件”的概念。我所说的“低级”其实是指“本机二进制文件”,因为我无法将我的应用程序部署到一些不允许安装.NET Framework的机器上。非常抱歉! - Kangjun Heo
显示剩余3条评论
3个回答

42
在C#中,var关键字只能在函数内部起作用。
var i = 10; // implicitly typed 

在C++中,auto关键字不仅可以推断变量的类型,还可以用于函数和模板。
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;
}

从性能角度来看,C++中的auto关键字不会影响运行时性能。而var关键字同样也不会影响运行时性能
另一个区别可能在于IDE中的智能感知支持。在C#中,可以轻松推断出var关键字,并且在悬停鼠标时可以看到类型。对于C++中的auto关键字,这可能更加复杂,这取决于IDE和工具的支持。

那么,auto 可以在更广泛的范围内使用吗? - Kangjun Heo
是的,在C++中使用auto,您可以通过强类型检查构建整个推理链。 - Tomas Kubes
var 在 C# 中不会影响性能,你提供的例子是错误的,因为 List<int> bar1 = Foo(); 会在编译时出错。请参考 Servy 的评论 - Lucas Trzesniewski
为什么它不会影响性能呢?我必须花费一些 CPU 时间来确定变量的类型,对吧?还是在编译期间确定?作为后续问题,为什么我们不只使用 auto? - Boyan Kushlev
1
是的,这个推断是在编译时进行的,所以性能不会受到影响。我不太喜欢使用auto/var,因为我喜欢在代码中看到类型,而不是通过鼠标悬停在每个变量上来查看。但如果类型非常复杂,我就会懒得写它,然后使用auto/var。 - Tomas Kubes
我认为一个普遍的好的经验法则是,当类型从名称或上下文中明显时,或者变量类型过长时使用auto/var。我曾经看到一些嵌套的模板迭代器超过一百个字符长度,这是可怕的事情! - Nemo

16
简而言之,autovar更为复杂。首先,auto可能只是被推导类型的一部分;例如:
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

其次,auto可以用于一次声明多个对象:

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

第三,auto被用作函数声明中的尾随返回类型语法的一部分:

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

它还可以用于函数定义中的类型推导:

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

第四,将来可能会开始用于声明函数模板:

void f(auto (auto::*mf)(auto));
// Same as:
template<typename T, typename U, typename V> void f(T (U::*mf)(V));

这应该是被接受的答案,即使它也错过了一些用途。1- auto&& 是使用通用引用的唯一其他地方。2- auto 可以用于 lambda 表达式参数。我猜我甚至还错过了一些用法。 - Tanveer Badar

7

它们是等效的。它们都允许您不必自己指定变量类型,但变量仍然是强类型的。下面这几行在C#中是等效的:

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

以下C++代码等效:

auto i = 10;
int i = 10;

然而,需要记住的是,在C++中,auto变量的正确类型是使用函数调用的模板参数推断规则来确定的。


1
加一。请注意,在某些情况下,C++中不可避免地需要使用auto - 例如当您使用lambda函数时。在C#中也是如此吗?另请注意auto i = 10;在C++11之前和之后意义非常不同(尽管在这种特定情况下,两个标准都将i设置为int类型)。 - Bathsheba
为什么不可避免?auto在编译时确实会解析为具体或通用类型。您可以将其替换为该具体类型。 - Panagiotis Kanavos
一个lambda函数的具体类型是什么? - Bathsheba
1
@Bathsheba 实际上你不能在C#中对于隐式类型的lambda表达式使用var。 你必须使用适当的委托类型(可以是Action<>Func<>之一)。因此实际上,就Lambda表达式而言,varauto并不等价。 - Matthew Watson
根据规范,“lambda表达式的类型(也是闭包对象的类型)是一个独特的、未命名的非联合类类型”。其中“未命名”的部分意味着auto是不可避免的。 - Gavi Lock
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接