header 中的概念不限制 C++20 中的参数包?
concept in header doesn't constrain a parameter pack in C++20?
上下文:我正在将使用 GCC -fconcepts 的库重写为 C++20。 Clang 10 和 GCC 10 给了我同样的意外问题,所以这可能是我的错。
我有一个支持两种情况的 class 模板。它可以从 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;
当我为 pins_out 列表编写专业化时,我可以编写概念 TS
template< pin_out_list... Ts >
struct port< Ts... > {};
但现在使用 C++20,编译器抱怨说专业化并不比基础更受限制。当我添加一个 requires 子句时,它会编译。
template< pin_out_list... Ts >
requires pin_out_list< Ts... >
struct port< Ts... > {};
我可以从模板 header.
中删除 pin_out_list...
template< typename... Ts >
requires pin_out_list< Ts... >
struct port< Ts... > {};
专业化中的 pin_out_list... 现在被默默忽略了吗?
上测试
P1141 改变的许多事情之一是可变约束的实际含义:
In [temp.param]/11 we have:
template <C2... T> struct s3; // associates C2<T...>
This seems to be doing an unexpected thing, which is having the constraint apply to more than one type in a pack at a time.
作为那篇论文的结果,像这样的可变约束现在适用于后面的每个类型。也就是说,我们现在有(现在在 [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...>;
你需要后面的意思(这是主表达式中的约束)所以你需要写后面的语法。编译器并没有默默地忽略你的专业化。
上下文:我正在将使用 GCC -fconcepts 的库重写为 C++20。 Clang 10 和 GCC 10 给了我同样的意外问题,所以这可能是我的错。
我有一个支持两种情况的 class 模板。它可以从 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;
当我为 pins_out 列表编写专业化时,我可以编写概念 TS
template< pin_out_list... Ts >
struct port< Ts... > {};
但现在使用 C++20,编译器抱怨说专业化并不比基础更受限制。当我添加一个 requires 子句时,它会编译。
template< pin_out_list... Ts >
requires pin_out_list< Ts... >
struct port< Ts... > {};
我可以从模板 header.
中删除 pin_out_list...template< typename... Ts >
requires pin_out_list< Ts... >
struct port< Ts... > {};
专业化中的 pin_out_list... 现在被默默忽略了吗?
上测试P1141 改变的许多事情之一是可变约束的实际含义:
In [temp.param]/11 we have:
template <C2... T> struct s3; // associates C2<T...>
This seems to be doing an unexpected thing, which is having the constraint apply to more than one type in a pack at a time.
作为那篇论文的结果,像这样的可变约束现在适用于后面的每个类型。也就是说,我们现在有(现在在 [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...>;
你需要后面的意思(这是主表达式中的约束)所以你需要写后面的语法。编译器并没有默默地忽略你的专业化。