用户定义类模板参数推导指南的缩写函数模板语法

Abbreviated function template syntax for user-defined class template argument deduction guide

提问人:Petwoip 提问时间:12/15/2022 最后编辑:max66Petwoip 更新时间:12/15/2022 访问量:143

问:

我正在以缩写函数模板的样式编写推导指南,但我不确定它是否被允许。它在 gcc 和 clang 上编译,但不在 msvc 上编译。

错误是:

错误 C3539:模板参数不能是包含“auto”的类型

哪个编译器在做正确的事情?

在这里试试吧

template <typename Type, int Count>
struct Array
{
    Type data[Count];

    Array (auto ... arg)
    {
        int count = 0;
        ((data[count++] = arg),...);
    }
};

// abbreviated function template syntax - fails in msvc
Array (auto first, auto ... next) -> Array<decltype(first), 1 + sizeof...(next)>;

// regular syntax
// template <typename Type, typename ... Args> Array (Type first, Args ... next) -> Array<Type, 1 + sizeof...(Args)>;

int main ()
{
    Array a(1,2,3);
}
C++ 语言-律师 C++20 演绎指南

评论

0赞 Remy Lebeau 12/15/2022
MSDN 文档中可以清楚地看出,msvc 不允许在默认的 /Zc:auto 模式下输入参数和模板参数。请参阅 C3533 和 C3539 auto

答:

4赞 user17732522 12/15/2022 #1

根据 [dcl.spec.auto.general]/6,不允许使用 [dcl.spec.auto] 中未明确允许的占位符类型(例如 )。auto

而且我没有看到任何适用于那里提到的扣除指南的内容。特别是 [dcl.spec.auto.general]/2,它允许在函数参数中使用,它被明确限制在函数声明和 lambda 表达式中的参数声明。

所以在我看来,它确实不合时宜。

但是,我看不出有任何理由。我怀疑 [dcl.spec.auto] 和 [dcl.fct] 中缩写函数模板的定义应该扩展为包含带有类似规则的推导指南的参数列表,以匹配 [temp.deduct.guide] 中的声明,即推导的参数列表遵循与函数声明相同的限制。

评论

1赞 Nicol Bolas 12/15/2022
为什么他们要鼓励人们在你肯定必须拥有一堆而不是仅仅使用的地方使用它?从广义上讲,在 lambda 之外,如果你曾经伸手去拿一个函数参数,你应该停下来写一个模板头。decltype(variable_name)templatedecltypeauto
1赞 user17732522 12/15/2022
@NicolBolas我真的不认为这是在函数/构造函数声明中添加不明显的语法差异的好理由,当演绎指南模仿它们时。但即便如此,例如,OP 的示例也不需要类型名称,也不需要使用占位符。(当然,您可能会考虑混合更糟糕的样式,但应该有不使用类型名称的示例。template<typename F> Array(F first, auto ... next) -> Array<F, 1 + sizeof...(next)>;decltypenext