我不清楚我正在查看的函数中 auto 的用法。给定一个定义如下的参数:
someFunction(const unique_ptr<BSTNode<int>>& node, paramType param) {
函数体建立了一个局部变量,如下所示:
auto *localNode = node.get();
我对 auto 的理解是,它在编译时推断出分配给它的类型。文档声明unique_ptr::get()
返回一个指向它管理的对象的指针。既然如此,为什么需要添加*
到变量声明中呢?
假设我有vector
成对,其中每个pair
对应于我正在处理的某个矩阵的索引(行和列)
using namespace std;
vector<pair<int, int>> vec;
Run Code Online (Sandbox Code Playgroud)
我想使用auto
遍历整个向量并立即删除满足某些条件的所有对,例如
for (auto& x : vec) {
if (x.first == x.second) {
vec.erase(x);
}
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用,因为我想vec.erase()
应该有一个迭代器作为参数,x
实际上pair
是一个 vector 元素vec
,而不是迭代器。我尝试以几种方式对其进行修改,但我不确定如何auto
准确地处理容器元素以及如何解决此问题。
我可以轻松修改上面的代码以使其工作并擦除 vector 的多个元素,同时使用auto
? 或者我应该修改我的方法?
现在它只是一个成对的向量,但以后会更糟,所以auto
为了简单起见,我想使用它。
我正在阅读这个问题的公认答案C++ Loop through Map
该答案中的一个示例:
for (auto const& x : symbolTable)
{
std::cout << x.first // string (key)
<< ':'
<< x.second // string's value
<< std::endl ;
}
Run Code Online (Sandbox Code Playgroud)
auto const&
在这种情况下是什么意思?
我想知道为什么在某些/所有情况下不可能完全省略 auto 关键字,例如
int main()
{
[](auto x){}(10); // why this?
[](x){}(10); // and not this?
auto x = 10;
x = 10;
}
Run Code Online (Sandbox Code Playgroud)
是否存在歧义或类似问题?还是简单的设计选择?
在以下代码中:
#include <iostream>
auto& print = std::cout; // Type deduction for std::cout works
auto& end = std::endl; // But the std::endl is exception here
int main(void) {
print << "Hello" << end;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
for 的类型推导std::cout
正确发生,但为什么它不适用于std::endl
?
注意:删除对运算符(与号)的引用也不起作用。
VS 代码说:
编译器生成以下内容:
$ g++ -Wall -O3 -std=c++14 -o main main.cpp; ./main
main.cpp:4:18: error: unable to deduce 'auto&' from 'std::endl'
4 | auto& end = std::endl; // But the std::endl is exception here
| ^~~~
main.cpp:4:18: note: …
Run Code Online (Sandbox Code Playgroud) 我知道使用auto
关键字可以自动从 Rvalue 推导出变量的类型。那为什么我的代码中下面的函数片段会出现编译错误呢?
auto getName(auto str = "John Doe") {
return str;
}
Run Code Online (Sandbox Code Playgroud)
编译错误是函数原型中不允许的“自动”。我用谷歌搜索了一下,我认为auto
不能在函数原型中使用。为什么这样?
我写了一个看起来像这样的函数:
auto fn(auto x) {
return x;
}
Run Code Online (Sandbox Code Playgroud)
我用不同的参数调用了它两次:
std::cout << fn(3124) << std::endl;
std::cout << fn("hello world") << std::endl;
Run Code Online (Sandbox Code Playgroud)
它工作正常,但我不明白为什么 - 我认为编译器推导出函数的常量返回类型 - int(由于第一次调用 - fn(3124))。似乎编译时生成的函数看起来像
template<typename T>;
T fn(T x) {
return x;
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么。请解释。
假设我们有一个带有运算符 [] 的类,如下所示
class MyClass
{
//...
public:
TYPE operator[](const size_t idx) const
{
//... Implementation
}
}
Run Code Online (Sandbox Code Playgroud)
现在我想阅读TYPE
并将其用作另一个类的模板参数。人们可能会使用一种技巧
template<class T>
class OtherClass
{
//...
}
template<class T>
auto generator(const T& element)
{
return OtherClass<T>();
}
int main(void)
{
MyClass myclass;
auto resulted_class = generator(myclass[0]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这应该创建一个OtherClass
with 模板TYPE
fromMyClass
并将其复制到resulted_class
.
现在的问题。是否有可能实现相同但没有对索引值 0 或任何特定索引值的 [] 运算符的通用调用?关键是不能保证 operator [] 是为特定值定义的。TYPE
如果可能,我们只需要提取。
换句话说,如果我们使用一个类,就像std::vector<double>
我们想double
从那个类中提取它一样。但在没有进一步了解的情况下std::vector
。我们唯一知道的是其中有 [] 运算符的定义。
如果我有一个重载的非静态成员函数,我如何auto
为该函数的一个版本声明一个指针?
struct Foo{
void bar(){}
void bar(int){}
};
auto ptr = &Foo::bar; // error: unable to deduce 'auto' from '&Foo::bar'
Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
#include <optional>
#include <string_view>
int main() {
std::optional<std::string_view> opt { "abc" };
std::cout << opt.value();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它编译并在运行时将“abc”输出到控制台。为什么要编译?main 中的第一行代码应该是:
std::optional<std::string_view> { std::string_view { "abc" } };
Run Code Online (Sandbox Code Playgroud)
编译器如何知道使用文字调用 string_view 构造函数?这似乎不仅仅是我以前见过的类型推导。这里似乎编译器正在向我的源代码添加代码,即对构造函数的调用。