可变模板参数与可变约束

huangapple go评论80阅读模式
英文:

Variadic template parameter with variadic constraint

问题

我有一个形如 template<C<T>... U> 的模板头,其中 C 是一个概念,而 T 是一组类型。U 将需要成为它自己的一组类型,但具体如何解析它呢?

例如在 <https://godbolt.org/z/MhG9YqsdK> 中的示例代码:

#include &lt;concepts&gt;

template&lt;typename... T&gt;
struct F {
    template&lt;std::same_as&lt;T&gt;... U&gt;
    static void f(U... args, void*);
};

int main() {
    F&lt;int, char&gt;::f(1, &#39;x&#39;, nullptr);
}

我认为 std::same_as&lt;T&gt; 是一个展开的模式,因此会展开为两个模板参数,如下所示:

template&lt;&gt;
struct F&lt;int, char&gt; {
    template&lt;std::same_as&lt;int&gt; U0, std::same_as&lt;char&gt; U1&gt;
    static void f(U0 arg0, U1 arg1, void*);
};

这似乎是clang所做的事情。而gcc似乎将其转换为:

template&lt;typename... T&gt;
struct F {
    template&lt;typename... U&gt; requires (std::same_as&lt;U, T&gt; &amp;&amp; ...)
    static void f(U... args, void*);
};

这使得 U 成为一个新的包,处于无法推导的上下文中(当无法推导 U 并且它是一个空包且 T 不是时会导致SFINAE错误)。

哪个编译器是正确的?我会假设[temp.variadic]p5是我要找的内容,如果这确实是一个包展开的话,但我不确定它是否适用。我也找不到标准中定义有约束的可变参数包的地方,以查看gcc的行为是否正确。

英文:

I have a template-head of the form template&lt;C&lt;T&gt;... U&gt;, where C is a concept and T is a pack of types. U will have to be its own pack, but how exactly is this parsed?

For example <https://godbolt.org/z/MhG9YqsdK>:

#include &lt;concepts&gt;

template&lt;typename... T&gt;
struct F {
    template&lt;std::same_as&lt;T&gt;... U&gt;
    static void f(U... args, void*);
};

int main() {
    F&lt;int, char&gt;::f(1, &#39;x&#39;, nullptr);
}

I would think that std::same_as&lt;T&gt; is a pattern for an expansion, so this expands to two template arguments, like:

template&lt;&gt;
struct F&lt;int, char&gt; {
    template&lt;std::same_as&lt;int&gt; U0, std::same_as&lt;char&gt; U1&gt;
    static void f(U0 arg0, U1 arg1, void*);
};

Which is what clang seems to do. What gcc seems to do is transform it like:

template&lt;typename... T&gt;
struct F {
    template&lt;typename... U&gt; requires (std::same_as&lt;U, T&gt; &amp;&amp; ...)
    static void f(U... args, void*);
};

which makes U a new pack in a non-deduced context (And a SFINAE error when U can't be deduced and is an empty pack and T isn't).

Which compiler is correct? I would assume [temp.variadic]p5 is what I am looking for if this was actually a pack expansion, but I'm not sure if it applies. I also can't find where in the standard constrained variadic parameter packs are defined to see if gcc's behaviour is correct.

答案1

得分: 1

这看起来像是GCC的一个错误,应该是一个包扩展:

[temp.param]/17

> ... 包含未展开参数包的类型约束的类型参数包是一个包扩展。

英文:

This looks like a GCC bug to me, it should be a pack expansion:

[temp.param]/17

> ... A type parameter pack with a type-constraint that contains an unexpanded parameter pack is a pack expansion. ...

huangapple
  • 本文由 发表于 2023年7月7日 02:11:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76631513.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定