我一直在使用c++ 11标准中提供的新的auto关键字来处理复杂的模板类型,我相信它就是为这个目的设计的。但我也用它来做以下事情:
auto foo = std::make_shared<Foo>();
更令人怀疑的是:
auto foo = bla(); // where bla() return a shared_ptr<Foo>
我还没有看到很多关于这个话题的讨论。auto似乎被滥用了,因为类型通常是一种文档和完整性检查的形式。你在使用auto方面的界限在哪里,这个新功能的推荐用例是什么?
澄清一下:我并不是在寻求哲学观点;我要求标准委员会对这个关键字的预期使用,可能还会对如何在实践中实现预期使用发表评论。
我认为,当第一眼就不知道如何写类型,但表达式右边的类型很明显时,应该使用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可以使编写代码更容易。
任何语言中的每一个新特性都会被至少某些类型的程序员过度使用。只有通过一些有经验的程序员(不是新手)适度的过度使用,其他有经验的程序员才能学会正确使用的界限。过度使用通常是不好的,但也可能是好的,因为这种过度使用可能会导致功能的改进或更好的功能来取代它。
但如果我写的代码不止几行,比如
auto foo = bla();
where the type is indicated zero times, I might want to change those lines to include types. The first example is great since the type is stated once, and auto saves us from having to write messy templated types twice. Hooray for C++++. But explicitly showing the type zero times, if it's not easily visible in a nearby line, makes me nervous, at least in C++ and its immediate successors. For other languages designed to work at a higher level with more abstraction, polymorphism and genericity, it's fine.
c++程序的一个主要问题是允许你使用未初始化的变量。这导致了我们讨厌的非确定性程序行为。应该注意的是,现代编译器现在抛出适当的/message警告消息,如果程序累了使用它。
为了说明这一点,考虑下面的c++程序:
int main() {
int x;
int y = 0;
y += x;
}
如果我使用现代编译器(GCC)编译这个程序,它会给出警告。这样的警告可能并非如此
如果我们使用的是真正复杂的产品代码,这是非常明显的。
main.cpp:在函数'int main()'中:
Main.cpp:4:8:警告:'x'在此函数中未初始化
(-Wuninitialized)
Y += x;
^
=================================================================================
现在如果我们改变我们的程序,使用auto,然后编译,我们得到如下:
int main() {
auto x;
auto y = 0;
y += x;
}
main.cpp:在函数'int main()'中:
Main.cpp:2:10:错误:声明'auto x'没有初始化式
汽车x;
^
对于auto,不可能使用未初始化的变量。如果我们开始使用auto,这是我们可以(免费)获得的主要优势。
c++专家Herb Shutter在他的CppCon14演讲中解释了这个概念和其他伟大的现代c++概念:
回归基本!现代c++风格要点
我认为,当第一眼就不知道如何写类型,但表达式右边的类型很明显时,应该使用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)
我指出的一个危险是在引用方面。
如。
MyBigObject& ref_to_big_object= big_object;
auto another_ref = ref_to_big_object; // ?
问题是,在这种情况下,another_ref实际上不是一个引用,它是MyBigObject而不是MyBigObject&。你最终复制了一个大对象而没有意识到它。
如果你直接从一个方法中得到一个引用,你可能不会考虑它实际上是什么。
auto another_ref = function_returning_ref_to_big_object();
你需要"auto&"或者"const auto&"
MyBigObject& ref_to_big_object= big_object;
auto& another_ref = ref_to_big_object;
const auto& yet_another_ref = function_returning_ref_to_big_object();