c++ 直接初始化参数中的auto(expression)

zzwlnbp8  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(96)

在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
GCC:

error: 'auto' parameter not permitted in this context


锵!

error: 'auto' not allowed in function prototype that is not a function declaration


y的声明真的非法吗?编译器拒绝它是正确的吗?

zz2j4svz

zz2j4svz1#

如果你有一个类型而不是auto,它会读起来像:

int y(int(long(x)));
// ->
int y(int(long x));
// ->
int y(int(*)(long));

字符串
但是,不能用auto代替long
[dcl.fct]p22:

  • 缩写函数模板 * 是具有一个或多个泛型参数类型占位符的函数声明([dcl.spec.auto])。

[dcl.spec.auto.general]p2
形式为 type-constraintoptauto的 * 占位符类型说明符 * 可以用作函数声明或 * parameter-declaration * 的 decl-specifier-seq 的 * decl-specifier*,如果不是auto * 类型说明符 *,则引入 trailing-return-type(见下文),是函数声明或 * 泛型表达式 * 的 * 泛型参数类型占位符 *。
.所以auto只能是直接在类型decl-specifier-seq中的decl-specifier,而不能进一步嵌套。基本上,如果你能把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 = ...;

int f(int);

auto (*ptr1)(int) = f;  // Works
// int (*ptr2)(auto) = f;  // Doesn't

相关问题