英文:
Variadic template parameter with variadic constraint
问题
我有一个形如 template<C<T>... U>
的模板头,其中 C
是一个概念,而 T
是一组类型。U
将需要成为它自己的一组类型,但具体如何解析它呢?
例如在 <https://godbolt.org/z/MhG9YqsdK> 中的示例代码:
#include <concepts>
template<typename... T>
struct F {
template<std::same_as<T>... U>
static void f(U... args, void*);
};
int main() {
F<int, char>::f(1, 'x', nullptr);
}
我认为 std::same_as<T>
是一个展开的模式,因此会展开为两个模板参数,如下所示:
template<>
struct F<int, char> {
template<std::same_as<int> U0, std::same_as<char> U1>
static void f(U0 arg0, U1 arg1, void*);
};
这似乎是clang所做的事情。而gcc似乎将其转换为:
template<typename... T>
struct F {
template<typename... U> requires (std::same_as<U, T> && ...)
static void f(U... args, void*);
};
这使得 U
成为一个新的包,处于无法推导的上下文中(当无法推导 U
并且它是一个空包且 T
不是时会导致SFINAE错误)。
哪个编译器是正确的?我会假设[temp.variadic]p5是我要找的内容,如果这确实是一个包展开的话,但我不确定它是否适用。我也找不到标准中定义有约束的可变参数包的地方,以查看gcc的行为是否正确。
英文:
I have a template-head of the form template<C<T>... U>
, 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 <concepts>
template<typename... T>
struct F {
template<std::same_as<T>... U>
static void f(U... args, void*);
};
int main() {
F<int, char>::f(1, 'x', nullptr);
}
I would think that std::same_as<T>
is a pattern for an expansion, so this expands to two template arguments, like:
template<>
struct F<int, char> {
template<std::same_as<int> U0, std::same_as<char> U1>
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<typename... T>
struct F {
template<typename... U> requires (std::same_as<U, T> && ...)
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的一个错误,应该是一个包扩展:
> ... 包含未展开参数包的类型约束的类型参数包是一个包扩展。
英文:
This looks like a GCC bug to me, it should be a pack expansion:
> ... A type parameter pack with a type-constraint that contains an unexpanded parameter pack is a pack expansion. ...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论