Auto关键字用于根据初始化推断变量的类型。但我在网上看到,自动无法确定功能参数的类型。我不明白auto在与函数参数一起使用时无法确定类型的原因。任何人都可以告诉我为什么auto不能用于函数参数以及auto关键字不能用于确定类型的任何其他情况。
答案 0 :(得分:7)
“不能”是一个强有力的词。毕竟,lambda参数可以使用auto
(在C ++ 14中)。它不是“不能”,而是“没有”。也许“不会”。
问题最终归结为:这实际上是做什么的?
void foo(auto x)
{
std::cout << x << std::endl;
}
auto
推论最终基于提供初始化表达式,用于推断实际类型。该声明不包含初始化表达式。
C ++是一种静态类型语言;这意味着编译器必须能够在编译时确定每个表达式和对象的类型。从上面开始,编译器可以推断出任何内容。
那么编译器如何知道std::cout << x
是合法的C ++语法?它只能说明operator<<
重载是否需要std::cout
和x
。在没有事先知道x
的类型的情况下,它无法弄清楚被调用的是什么。它没有;对于函数的不同调用,它可以是不同的。
但是,有一个C ++构造,其中上述有意义:模板。这正是在lambda参数中使用auto
的原因;它隐式地将函数转换为模板函数。所以[](auto x) {return x;}
实际上变成了这样的运算符:
template<typename T>
auto operator()(T x) {return x;}
但是,此转换不仅仅是将auto
作为演绎语法。它必须是标准明确写入要求的东西。而且,除了C ++ 14泛型lambdas之外,它没有。
概念TS包括此功能。但是,这仅仅是在函数参数列表中使用概念的能力的扩展。也就是说,他们已经有办法让函数隐式创建模板函数,所以他们只是添加auto
本质上是“接受任何类型的概念”。
但这是从C ++ 20版本的概念中明确排除。这种排除的一般原因是,到目前为止,可以检测模板函数,因为它们总是必须具有一些特殊的语法。即,诱导物template<args>
。使用Concepts TS版本,人们担心人们会在没有意识到的情况下编写模板函数。
模板函数的行为与非模板函数不同。模板函数是一系列函数,因此您无法获得指向族本身的指针。您必须显式实例化模板以获取指向该特定函数的指针。