我一直在使用c++ 11标准中提供的新的auto关键字来处理复杂的模板类型,我相信它就是为这个目的设计的。但我也用它来做以下事情:
auto foo = std::make_shared<Foo>();
更令人怀疑的是:
auto foo = bla(); // where bla() return a shared_ptr<Foo>
我还没有看到很多关于这个话题的讨论。auto似乎被滥用了,因为类型通常是一种文档和完整性检查的形式。你在使用auto方面的界限在哪里,这个新功能的推荐用例是什么?
澄清一下:我并不是在寻求哲学观点;我要求标准委员会对这个关键字的预期使用,可能还会对如何在实践中实现预期使用发表评论。
我使用auto的一个痛苦经历是在lambda表达式中使用它:
auto i = []() { return 0; };
cout<<"i = "<<i<<endl; // output: 1 !!!
实际上,这里i被解析为int(*)()的函数指针。这只是一个简单的cout,但是想象一下,当它与template一起使用时,会导致什么样的编译/运行时错误。
你应该避免使用这样的表达式,并设置一个合适的返回类型(或受控的decltype())
上述例子的正确用法是:
auto i = []() { return 0; }(); // and now i contains the result of calling the lambda
是的,它可能被过度使用而损害可读性。我建议在这样的情况下使用它:确切的类型很长,或者无法表达,或者对可读性不重要,并且变量的寿命很短。例如,迭代器类型通常很长,不重要,所以auto可以工作:
for(auto i = container.begin(); i != container.end(); ++i);
这里的Auto不会影响可读性。
另一个例子是解析器规则类型,它可能很长很复杂。比较:
auto spaces = space & space & space;
with
r_and_t<r_and_t<r_char_t<char>&, r_char_t<char>&>, r_char_t<char>&> spaces =
space & space & space;
另一方面,当类型是已知的并且是简单的,如果显式地声明它会更好:
int i = foo();
而不是
auto i = foo();
我认为,当第一眼就不知道如何写类型,但表达式右边的类型很明显时,应该使用auto关键字。例如,使用:
my_multi_type::nth_index<2>::type::key_type::composite_key_type::
key_extractor_tuple::tail_type::head_type::result_type
要在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)
我使用auto的一个痛苦经历是在lambda表达式中使用它:
auto i = []() { return 0; };
cout<<"i = "<<i<<endl; // output: 1 !!!
实际上,这里i被解析为int(*)()的函数指针。这只是一个简单的cout,但是想象一下,当它与template一起使用时,会导致什么样的编译/运行时错误。
你应该避免使用这样的表达式,并设置一个合适的返回类型(或受控的decltype())
上述例子的正确用法是:
auto i = []() { return 0; }(); // and now i contains the result of calling the lambda
在c++和超越2012的Ask Us Anything小组中,Andrei Alexandrescu、Scott Meyers和Herb Sutter就何时使用和不使用auto进行了一次精彩的交流。跳到25:03分钟进行4分钟的讨论。这三位演讲者都给出了很好的观点,应该记住什么时候不使用auto。
我非常鼓励人们得出自己的结论,但我的结论是在任何地方都要使用auto,除非:
这会影响可读性
关心自动类型转换(例如,从构造函数,赋值,模板中间类型,整数宽度之间的隐式转换)
自由地使用explicit有助于减少对后者的关注,这有助于最大限度地减少前者成为问题的时间。
换句话说,Herb说,“如果你不做X, Y和Z,用auto。了解X, Y和Z是什么,然后在其他地方使用auto。”