我正在学习使用C ++ 11的东西,遇到了我不确定如何使用auto
的情况。考虑一下:
struct MyClass { double x; }
std::vector<MyClass*> myvec;
function_that_fills_vector(myvec);
//(1) this should be valid:
for(auto* item : myvec){ std::cout<< item->x <<std::endl; }
//(2) what about this?
for(auto item : myvec){ std::cout<< item.x <<std::endl; }
//(3) or this?
for(auto item : myvec){ std::cout<< item->x <<std::endl; }
也就是说,如果我知道我的auto
确实是一个指针,我可以在构造函数中明确它,所以我知道解引用运算符是正确的。但是如果我改变myvec
来保存对象,(1)将不再编译。
在(2)和(3)中,底层指针的性质是隐含的。哪个成员访问运算符(.
或->
)是正确的?如果两者都有效,是否有充分理由使用其中一种?如果我将myvec
更改为vector<MyClass>
,两者都会继续有效吗?
答案 0 :(得分:4)
auto
不会更改该类型的类型或用法。
通常只有一个编译。使用它。
答案 1 :(得分:3)
您应该使用编译器来解决这个问题!
这是一个完整的文件:
#include <iostream>
#include <vector>
struct MyClass {
double x;
};
int main() {
struct MyClass m;
std::vector<MyClass*> myvec;
myvec.push_back(&m);
for(auto* item : myvec){ std::cout<< item->x <<std::endl; }
for(auto item : myvec){ std::cout<< item.x <<std::endl; }
for(auto item : myvec){ std::cout<< item->x <<std::endl; }
}
然后我们可以查看编译器输出:
$ g++ fun.cc
fun.cc: In function ‘int main()’:
fun.cc:14:44: error: request for member ‘x’ in ‘item’, which is of pointer type ‘MyClass*’ (maybe you meant to use ‘->’ ?)
for(auto item : myvec){ std::cout<< item.x <<std::endl; }
如果你删除第14行(第二个例子),一切都会编译。换句话说:
在第一个例子中,auto指的是MyClass。
在第二种情况下,它必须引用MyClass *,但是您无法使用&#39;来访问其成员。&#39;。
在第三部分,它指的是MyClass *。
答案 2 :(得分:0)
这是两条相同的线。变量的类型是MyClass *
//(1) this should be valid:
for(auto* item : myvec){ std::cout<< item->x <<std::endl; }
//(3) or this?
for(auto item : myvec){ std::cout<< item->x <<std::endl; }
但是这行不应该编译。因为变量的类型将是MyClass *,并且您尝试通过运算符访问成员。
//(2) what about this?
for(auto item : myvec){ std::cout<< item.x <<std::endl; }
答案 3 :(得分:0)
将根据编译器可以推断出的类型来确定类型。来自https://en.cppreference.com/w/cpp/language/auto
对于变量,指定所要变量的类型 声明的内容将从其初始值设定项中自动推导出。
因此,基本上,它将尝试可推断的类型,如果找到匹配的类型,它将使用该类型。
也许,如果您要询问汽车要推导的类型,那么您可能会足够在意指定类型。但是您不能使用'。'确实有意义。对于指针变量类型,没有任何类型可以推导该类型。
无论阅读此代码的人员是什么人,都会看到您正在使用->表示法,并且可以假定您具有指针类型或->运算符重载。因此,如果您想明确表示它绝对是一个指针,请继续。到头来,它只会真正帮助提高可读性,两者都一样容易编写。