'auto'作为函数参数的模板参数占位符


22

C ++ 20允许使用auto函数参数类型。

它是否还允许将函数参数类型auto用作模板参数占位符(不相似,但以C ++ 17 template <auto>的精神)。

因此,以下代码是C ++ 20之前的版本:

template<typename First, typename Second>
void printPair(const std::pair<First, Second>& p) {
    std::cout << p.first << ", " << p.second;
}

可以写成:

void printPair(const std::pair<auto, auto>& p) {
    std::cout << p.first << ", " << p.second;
}

确实可以编译,并且可以很好地与实验性GCC实现概念配合使用。

它是C ++ 20的合法语法吗?


根据我所听到的,不受约束的auto 直接转换为templateized typename XYZ,这将强烈暗示它是合法的语法。整洁
Fureeish

2
请注意,Clang 表示不同意,而Clang和GCC在是否auto允许使用[](const std::pair<auto, auto>& p){}-std=c++2a-std=c++17)方面也存在相同的分歧。
胡桃


谢谢@DavisHerring-我已纠正措辞
Amir Kirsh

Answers:


17

此语法在C ++概念技术规范中有效,但在C ++ 20中无效。在C ++ 20概念中,auto仅允许在函数参数类型的顶级使用。相关规则是[dcl.spec.auto]第2段

占位符型说明符形式的类型约束 [选择] auto可以被用作一个DECL说明符的的DECL说明符-SEQ一个的参数声明函数声明或λ-表达,如果它不是auto 类型说明符引入尾返回型(见下文),是一种通用的参数类型占位符的函数声明或λ-表达。[注意:具有通用参数类型占位符表示该函数是缩写的函数模板(9.3.3.5 [dcl.fct])或lambda是通用lambda(7.5.5 [expr.prim.lambda])。—尾注]

(如果您在撰写本文时检查了最新工作草案中的措辞,您会发现一条不同的规则。以上规则已被核心问题2447修改,该问题在布拉格的C ++ 20最终草案中被投票通过一周前的委员会会议。)

DECL说明符 S IN的函数的参数是关键字,类型名称在参数声明的开始的初始序列。上面的规则允许auto出现在顶层:

void f(auto x);

...但仅作为decl-specifierauto当嵌套在decl-specifier中时是不允许的:

void f(std::vector<auto> x);

...,并且在参数类型的其他地方也不允许:

void f(void (*p)(auto));

哇,我不知道!CWG链接当前提供404,因此您能否简要说明此限制的原理?
LF

这是完全令人失望的。
Fureeish

1
抱歉,CWG问题及其措辞更改尚未公开。有问题的规则由open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1141r2.html引入,其目的/理由应与我们已经允许的通用lambda保持一致。
理查德·史密斯

4
@LF:CWG问题实际上并不是真正相关的问题:它纠正了一个措词错误,该错误暗示着auto将尾随返回类型的某些用法算作这种auto用法。
戴维斯鲱鱼
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.