我一直在使用c++ 11标准中提供的新的auto关键字来处理复杂的模板类型,我相信它就是为这个目的设计的。但我也用它来做以下事情:
auto foo = std::make_shared<Foo>();
更令人怀疑的是:
auto foo = bla(); // where bla() return a shared_ptr<Foo>
我还没有看到很多关于这个话题的讨论。auto似乎被滥用了,因为类型通常是一种文档和完整性检查的形式。你在使用auto方面的界限在哪里,这个新功能的推荐用例是什么?
澄清一下:我并不是在寻求哲学观点;我要求标准委员会对这个关键字的预期使用,可能还会对如何在实践中实现预期使用发表评论。
什么汽车?
它告诉编译器根据变量的初始值推断(确定)变量的数据类型。它使用类型演绎。
auto应该用在哪里?
当你对变量的类型不感兴趣时
想要使用它。
当你想要避免非常长和丑陋的typename。
当你不确定自己的类型时。
当你不想在你的代码中看到未初始化的变量。
Auto强制你初始化一个变量,因此你不能忘记做
那
当它不应该使用或缺点的自动
参考它的功能,auto可能会错误地推断类型,1
这种情况是
Std::vector<bool> vec(10,0);
Auto x = vec[2];
Bool y = vec[2];
Std::cout << typeid(x).name() << "\n";
Std::cout << typeid(y).name() << "\n";
g++ 10.2上的输出令人惊讶:
St14_Bit_reference
b
如果你想让你的代码可读&,不应该使用它
对其他人来说是可以理解的。它隐藏了数据类型的可见性
来自读者。
我指出的一个危险是在引用方面。
如。
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();
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)