DxA*_*pha 141 c++ type-inference auto c++11
这似乎auto是一个相当重要的功能,在C++ 11中添加似乎遵循许多较新的语言.与像Python这样的语言一样,我没有看到任何显式变量声明(我不确定是否可以使用Python标准).
使用auto声明变量而不是显式声明它们有缺点吗?
Pet*_*ter 110
你只问了一些缺点,所以我突然强调其中一些.如果用得好,auto也有几个优点.这些缺点源于易于滥用,以及代码以非预期方式运行的可能性增加.
主要缺点是,通过使用auto,您不一定知道正在创建的对象的类型.在某些情况下,程序员可能希望编译器推导出一种类型,但编译器坚决推断另一种类型.
给出类似的声明
auto result = CallSomeFunction(x,y,z);
Run Code Online (Sandbox Code Playgroud)
你不一定知道什么类型result.它可能是一个int.它可能是一个指针.它可能是别的东西.所有这些都支持不同的操作.您还可以通过稍微改变来显着更改代码
auto result = CallSomeFunction(a,y,z);
Run Code Online (Sandbox Code Playgroud)
因为,取决于CallSomeFunction()结果类型存在的重载可能完全不同 - 因此后续代码的行为可能与预期完全不同.您可能会在以后的代码中突然触发错误消息(例如,随后尝试取消引用int,尝试更改现在的内容const).更加险恶的变化是你的变化超越编译器的地方,但随后的代码表现在不同的和未知的 - 可能是错误的 - 方式.
因此,没有明确知道某些变量的类型会使得更难以严格证明代码按预期工作的说法.这意味着需要更多的努力来证明在高关键性(例如安全关键或关键任务)领域中"适合目的"的主张.
另一个更常见的缺点是程序员使用它auto作为一种钝器来强制编译代码,而不是考虑代码正在做什么,并努力使其正确.
Nir*_*man 75
这不是auto原则上的一个缺点,但实际上对某些人来说似乎是一个问题.基本上,有些人是:a)治疗auto作为类型救世主和使用时关闭他们的大脑关闭,或B)忘了,auto总是推导值类型.这导致人们做这样的事情:
auto x = my_obj.method_that_returns_reference();
Run Code Online (Sandbox Code Playgroud)
哎呀,我们只是深深地复制了一些对象.它通常是错误或性能失败.然后,你也可以摆动另一种方式:
const auto& stuff = *func_that_returns_unique_ptr();
Run Code Online (Sandbox Code Playgroud)
现在你得到一个悬垂的参考.这些问题根本不是由问题引起的auto,所以我不认为它们是反对它的合法论据.但auto由于我在开始时列出的原因,似乎使这些问题更常见(根据我的个人经验).
我想给定的时间人们会调整,并理解分工:auto推断的基础类型,但你还是要想想参考的烦躁和常量性.但这需要一些时间.
Rei*_*ica 51
其他答案提到的缺点是"你真的不知道变量的类型是什么." 我会说这很大程度上与代码中的草率命名约定有关.如果您的接口名称清晰,则无需关心确切的类型.当然,auto result = callSomeFunction(a, b);不要告诉你太多.但是auto valid = isValid(xmlFile, schema);告诉你足够使用valid而不必关心它的确切类型.毕竟,只是if (callSomeFunction(a, b)),你也不会知道这种类型.与任何其他子表达式临时对象相同.所以我不认为这是一个真正的缺点auto.
我要说它的主要缺点是,有时,确切的返回类型不是你想要使用的.实际上,有时实际返回类型与"逻辑"返回类型不同,作为实现/优化细节.表达模板是一个很好的例子.假设我们有这个:
SomeType operator* (const Matrix &lhs, const Vector &rhs);
Run Code Online (Sandbox Code Playgroud)
从逻辑上讲,我们希望SomeType如此Vector,我们绝对希望在我们的代码中对待它.但是,出于优化目的,我们使用的代数库可以实现表达式模板,实际的返回类型是这样的:
MultExpression<Matrix, Vector> operator* (const Matrix &lhs, const Vector &rhs);
Run Code Online (Sandbox Code Playgroud)
现在,问题是很MultExpression<Matrix, Vector>可能存储const Matrix&和const Vector&内部存储; 它期望它将Vector在其完整表达式结束之前转换为a .如果我们有这个代码,一切都很好:
extern Matrix a, b, c;
extern Vector v;
void compute()
{
Vector res = a * (b * (c * v));
// do something with res
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我们在auto这里使用过,我们可能遇到麻烦:
void compute()
{
auto res = a * (b * (c * v));
// Oops! Now `res` is referring to temporaries (such as (c * v)) which no longer exist
}
Run Code Online (Sandbox Code Playgroud)
ks1*_*322 13
唯一的缺点是,有时你不能声明const_iterator与auto.你会得到普通(非const的)迭代器在取自代码这个例子中这个问题:
map<string,int> usa;
//...init usa
auto city_it = usa.find("New York");
Run Code Online (Sandbox Code Playgroud)
Ska*_*kam 11
它使您的代码更难或更乏味,无法阅读.想象一下这样的事情:
auto output = doSomethingWithData(variables);
Run Code Online (Sandbox Code Playgroud)
现在,要弄清楚输出的类型,你必须追踪doSomethingWithData功能的签名.
像这个开发者一样,我讨厌auto.或者更确切地说,我讨厌人们如何滥用auto.
我(强烈)意见auto是帮助你编写通用代码,而不是减少输入.
C++是一种语言,其目标是让您编写健壮的代码,而不是最小化开发时间.
从C++的许多功能来看,这是相当明显的,但不幸的是,一些较新的类似auto减少输入误导人们认为他们应该开始懒惰打字.
在auto过去,人们使用typedefs,这很棒,因为typedef 允许图书馆的设计师帮助你弄清楚返回类型应该是什么,以便他们的图书馆按预期工作.当你使用时auto,你从类的设计者那里拿走那个控件,而不是要求编译器弄清楚应该是什么类型,这会从工具箱中删除一个最强大的C++工具,并有可能破坏他们的代码.
通常,如果你使用auto,那应该是因为你的代码适用于任何合理的类型,而不是因为你只是懒得写下它应该使用的类型.如果你auto用作帮助懒惰的工具,那么你最终会开始在程序中引入微妙的错误,这通常是由于你使用过而没有发生的隐式转换引起的auto.
不幸的是,这些错误是很难说明在很短的例子在这里,因为他们的简洁使他们比上来的用户项目的实际例子那么令人信服-不过,他们在期待某一模板的重码容易出现隐式转换采取地点.
如果你想要一个例子,有一个在这里.但需要注意的是:在尝试跳跃并批评代码之前:请记住,围绕这种隐式转换开发了许多知名且成熟的库,并且它们存在,因为它们解决了即使不是不可能也很难解决的问题否则解决.在批评之前尝试找出更好的解决方案.
auto没有缺点本身,我提倡(手波浪)在新代码中任何地方使用它.它允许您的代码始终进行类型检查,并始终避免静默切片.(如果B派生自A并且函数返回A突然返回B,则auto表现为按预期存储其返回值)
虽然,预C++ 11遗留代码可能依赖于使用显式类型变量引起的隐式转换.将显式类型变量auto更改为可能会更改代码行为,因此您最好小心谨慎.
| 归档时间: |
|
| 查看次数: |
12157 次 |
| 最近记录: |