Ala*_*ing 210 c++ types type-inference auto c++11
我一直在使用autoC++ 11标准中提供的新关键字来处理复杂模板类型,这是我认为它的设计目标.但我也用它来做:
auto foo = std::make_shared<Foo>();
Run Code Online (Sandbox Code Playgroud)
更加怀疑的是:
auto foo = bla(); // where bla() return a shared_ptr<Foo>
Run Code Online (Sandbox Code Playgroud)
我没有看到很多关于这个话题的讨论.似乎auto可能过度使用,因为类型通常是文档和健全性检查的一种形式.您在哪里绘制使用线auto以及此新功能的推荐用例是什么?
澄清:我不是要求哲学观点; 我要求标准委员会对该关键字的预期用途,可能还有关于如何在实践中实现该预期用途的评论.
旁注:此问题已移至SE.Programmers,然后返回Stack Overflow.关于这一点的讨论可以在这个元问题中找到.
Kir*_*sky 124
我认为auto只要很难说第一眼看到如何写类型就应该使用关键字,但表达式右侧的类型是显而易见的.例如,使用:
my_multi_type::nth_index<2>::type::key_type::composite_key_type::
key_extractor_tuple::tail_type::head_type::result_type
Run Code Online (Sandbox Code Playgroud)
获取复合键类型boost::multi_index,即使你知道它是int.你不能只是写,int因为它可以在将来改变.我会写auto这个案子.
因此,如果auto关键字提高了特定情况下的可读性,则使用它.auto当读者明白哪种类型auto代表时,你可以写.
这里有些例子:
auto foo = std::make_shared<Foo>(); // obvious
auto foo = bla(); // unclear. don't know which type `foo` has
const size_t max_size = 100;
for ( auto x = max_size; x > 0; --x ) // unclear. could lead to the errors
// since max_size is unsigned
std::vector<some_class> v;
for ( auto it = v.begin(); it != v.end(); ++it )
// ok, since I know that `it` has an iterator type
// (don't really care which one in this context)
Run Code Online (Sandbox Code Playgroud)
Jon*_*rdy 60
尽可能auto在任何地方使用- 特别是const auto这样可以减少副作用.除了明显的情况外,您不必担心类型,但它们仍然会为您进行静态验证,并且您可以避免重复.在auto不可行的地方,您可以使用decltype语义表达类型作为基于表达式的契约.您的代码看起来会有所不同,但这将是一个积极的变化.
spr*_*aff 48
简单.当你不在乎什么类型时使用它.例如
for (const auto & i : some_container) {
...
Run Code Online (Sandbox Code Playgroud)
我所关心的就是i容器中的任何东西.
这有点像typedef.
typedef float Height;
typedef double Weight;
//....
Height h;
Weight w;
Run Code Online (Sandbox Code Playgroud)
在这里,我不在乎是否h和w是浮动还是双打,只是他们是什么类型适合于表达高度和重量.
或考虑一下
for (auto i = some_container .begin (); ...
Run Code Online (Sandbox Code Playgroud)
这里我关心的是它是一个合适的迭代器,支持operator++(),就像在这方面的鸭子打字.
lambda的类型也不能拼写,所以auto f = []...风格也很好.替代方案是铸造,std::function但随之而来的是开销.
我无法想象一个"虐待" auto.我能想象到的最接近的是剥夺了自己对某种重要类型的显式转换 - 但你不会使用auto它,你构建了一个所需类型的对象.
如果你可以删除代码中的一些冗余而不引入副作用,那么这样做一定很好.
反例(借用别人的答案):
auto i = SomeClass();
for (auto x = make_unsigned (y); ...)
Run Code Online (Sandbox Code Playgroud)
在这里我们关心类型是什么,所以我们应该写Someclass i;和for(unsigned x = y;...
Dar*_*enW 43
去吧.使用auto它可以使编写代码更容易.
任何语言的每个新功能都会被至少某些类型的程序员过度使用.只有通过一些有经验的程序员(而不是新手)适度过度使用,其他有经验的程序员才能学会正确使用的界限.极度过度使用通常很糟糕,但可能会很好,因为这种过度使用可能会导致功能的改进或更换功能的更好功能.
但是,如果我正在使用多行代码来处理代码
auto foo = bla();
Run Code Online (Sandbox Code Playgroud)
如果类型指示为零次,我可能想要更改这些行以包括类型.第一个例子很棒,因为类型被陈述一次,并且使auto我们不必两次编写凌乱的模板类型.Hooray for C++++.但明确显示类型零次,如果它在附近的行中不容易看到,会让我感到紧张,至少在C++及其直接后继者中.对于其他设计为在更高层次上工作且具有更多抽象,多态性和通用性的语言,它很好.
Gen*_*yev 36
是的,它可能被过度使用而不利于可读性.我建议在确切类型很长,或者说不可知,或者对可读性不重要的上下文中使用它,并且变量是短暂的.例如,迭代器类型通常很长并且不重要,因此auto可以工作:
for(auto i = container.begin(); i != container.end(); ++i);
Run Code Online (Sandbox Code Playgroud)
auto 这里不会伤害可读性.
另一个例子是解析器规则类型,它可以很长并且是复杂的.相比:
auto spaces = space & space & space;
Run Code Online (Sandbox Code Playgroud)
同
r_and_t<r_and_t<r_char_t<char>&, r_char_t<char>&>, r_char_t<char>&> spaces =
space & space & space;
Run Code Online (Sandbox Code Playgroud)
另一方面,当类型已知并且很简单时,如果明确说明它会更好:
int i = foo();
Run Code Online (Sandbox Code Playgroud)
而不是
auto i = foo();
Run Code Online (Sandbox Code Playgroud)
Sea*_*ean 36
在C++和2012年之后的Ask Us Anything小组中,Andrei Alexandrescu,Scott Meyers和Herb Sutter之间auto进行了一次精彩的交流,谈论何时使用而不使用.跳到分钟25:03进行4分钟的讨论.所有三个扬声器都提供了优秀的要点,在不使用时应牢记这一点auto.
我强烈鼓励人们得出自己的结论,但我的收获是到处使用auto,除非:
自由使用explicit有助于减少对后者的关注,这有助于最大限度地减少前者成为问题的时间.
重写赫伯所说的,"如果你不做X,Y和Z,请使用auto.了解X,Y和Z是什么,然后auto在其他地方使用."
mor*_*paj 18
auto 与表达模板结合使用会非常危险,这些表达模板被线性代数库(如Eigen或OpenCV)大量使用.
auto A = Matrix(...);
auto B = Matrix(...);
auto C = A * B; // C is not a matrix. It is a matrix EXPRESSION.
cout << C; // The expression is evaluated and gives the expected result.
... // <code modifying A or B>
cout << C; // The expression is evaluated AGAIN and gives a DIFFERENT result.
Run Code Online (Sandbox Code Playgroud)
由此类错误引起的错误是调试的主要难题.一种可能的补救方法是,如果您希望使用auto来实现从左到右的声明样式,那么将结果显式地转换为期望的类型.
auto C = Matrix(A * B); // The expression is now evaluated immediately.
Run Code Online (Sandbox Code Playgroud)
raf*_*fak 10
我使用autowihout限制,并没有遇到任何问题.我有时甚至最终会将它用于简单的类型int.这使得c ++成为我的高级语言,并允许在c ++中声明变量,就像在python中一样.编写python代码后,我甚至有时会写例如
auto i = MyClass();
Run Code Online (Sandbox Code Playgroud)
代替
MyClass i;
Run Code Online (Sandbox Code Playgroud)
这是一个案例,我会说这是滥用auto关键字.
通常我不介意对象的确切类型是什么,我对它的功能更感兴趣,并且因为函数名称通常会说出它们返回的对象,auto不会受到伤害:例如auto s = mycollection.size(),我可以猜测它s会是一种整数,在极少数情况下,我关心确切的类型,让我们检查函数原型然后(我的意思是,我更愿意检查何时需要信息,而不是在编写代码时的先验,只是如果有一天它将是有用的,如在int_type s = mycollection.size()).
关于这个例子来自公认的答案:
for ( auto x = max_size; x > 0; --x )
Run Code Online (Sandbox Code Playgroud)
在我的代码中,我仍然auto在这种情况下使用,如果我想要x无符号,那么我使用一个名为say的实用函数make_unsigned,它清楚地表达了我的担忧:
for ( auto x = make_unsigned(max_size); x > 0; --x )
Run Code Online (Sandbox Code Playgroud)
免责声明:我只是描述我的使用,我不能提供建议!