在 C++23 中,我们有显式类型转换
auto ( expression )
,并且根据 cppreference 它已经被 GCC 和 Clang 支持。
我有一个问题,由于某种原因,这种转换不会发生。考虑该程序:
// OK, x = 0
int x(int(auto(0)));
// OK, f is function template
int f(auto(x));
// error
int y(int(auto(x)));
此处
x
声明被接受,但非常相似的 y
声明则不被接受。在线演示:https://godbolt.org/z/f9zor3eTv
海湾合作委员会:
error: 'auto' parameter not permitted in this context
叮当:
error: 'auto' not allowed in function prototype that is not a function declaration
y
的声明真的非法并且编译器拒绝它是正确的吗?
如果你有一个类型而不是
auto
,它会读成这样:
int y(int(long(x)));
// ->
int y(int(long x));
// ->
int y(int(*)(long));
但是,您不能用
auto
代替 long
。
缩写函数模板是一种具有一个或多个泛型参数类型占位符 ([dcl.spec.auto]) 的函数声明。 [...]
type-constraintopt
auto
形式的placeholder-type-specifier可以用作parameter-declaration的decl-specifier-seq的decl-specifier函数声明或 lambda 表达式,如果它不是引入trailing-return-type(见下文)的auto
type-specifier,则为函数声明的 泛型参数类型占位符或 lambda 表达式。
...所以
auto
只能是直接位于类型的decl-specifier
中的decl-specifier-seq
,不能进一步嵌套。基本上,如果您可以将 auto
一直移到左侧,就可以了。
所以这些缩写函数模板可以工作:
int y(auto x);
int y(auto* x);
int y(auto const*& x);
int y(const auto*& x);
int y(auto* x[][12]);
int y(auto (*x)[3][4]);
int y(auto (*fn)(int x));
// Last one can be written as:
int y(auto(int x));
int y(auto(int(x)));
这些不会:
int y(std::vector<auto> x);
int y(void (*fn)(auto));
int y(int x[sizeof(auto)]);
完全相同的限制适用于初始值设定项中的占位符类型,例如
auto x = ...;
。