c++ - 标头中的概念不限制 C++20 中的参数包?
问题描述
上下文:我正在将一个与 GCC -fconcepts 一起使用的库重写为 C++20。Clang 10 和 GCC 10 给了我同样的意外问题,所以这可能是我的错。
我有一个支持两种情况的类模板。它可以从 pin_out 列表创建,也可以从 port_out 列表创建。
template< typename T > concept pin_out = T::is_pin_out;
template< typename... Ts > concept pin_out_list = ( pin_out< Ts > && ... );
template< typename T > concept port_out = T::is_port_out;
template< typename... Ts >
requires pin_out_list< Ts...> || ( port_out< Ts > && ... )
struct port;
当我用我可以写的概念 TS 编写一个 pin_out 列表的专业化时
template< pin_out_list... Ts >
struct port< Ts... > {};
但是现在有了 C++20,编译器抱怨专业化并不比基础更受限制。当我添加一个 requires 子句时,它会编译。
template< pin_out_list... Ts >
requires pin_out_list< Ts... >
struct port< Ts... > {};
我可以从模板标题中删除 pin_out_list...。
template< typename... Ts >
requires pin_out_list< Ts... >
struct port< Ts... > {};
现在专业化中的 pin_out_list... 是否被默默地忽略了?
在编译器资源管理器上测试它
解决方案
P1141改变的许多事情之一是可变参数约束的实际含义:
在 [temp.param]/11 我们有:
template <C2... T> struct s3; // associates C2<T...>
这似乎是在做一件意想不到的事情,即一次将约束应用于一个包中的多个类型。
由于那篇论文,像这样的可变参数约束现在适用于后面的每种类型。也就是说,我们现在有(现在在[temp.param]/5中):
template <C2... T> struct s3; // associates (C2<T> && ... )
因此,该专业化:
template< pin_out_list... Ts >
struct port< Ts... > {};
方法:
template <typename... Ts> requires (pin_out_list<Ts> && ...)
struct port<Ts...>;
并不是:
template <typename... Ts> requires pin_out_list<Ts...>
struct port<Ts...>;
您需要后一种含义(这是主表达式中的约束),因此您需要编写后一种语法。编译器并没有默默地忽略您的专业化。
推荐阅读
- sql - 视图中的 SQL 更新表
- ldap - OpenLDAP 搜索过滤器 DN 语法错误 (34) 身份验证失败
- python - 如何将所有 .txt 文件加载到具有不同名称的文件夹中 - Python
- electron - 我在哪里可以看到电子生成器自定义 NSIS 包含脚本中的回声输出?
- html - 使用 Golang 在特定打印机上打印 HTML
- reactjs - 内联使用情绪反应主题颜色
- javascript - 如何使用 formdata reactjs 发布图像数组
- http - 尽管 WriteHeader 用于返回另一个状态代码,但返回 200 状态代码
- ios - iOS SystemConfiguration plist - 更改HTTP代理不生效
- ios - 用画笔快速绘制