[英]C++20 concept that supposedly depends on itself
In my world, a StrictNodeType
should be anything that defines the types PredContainer
and SuccContainer
, so I wrote在我的世界中,
StrictNodeType
应该是定义PredContainer
和SuccContainer
类型的任何东西,所以我写了
template<typename N>
concept StrictNodeType = requires {
typename N::PredContainer;
typename N::SuccContainer;
};
However, GCC-11.2 gives me the following error:但是,GCC-11.2 给了我以下错误:
error: satisfaction of atomic constraint 'requires{typename N::PredContainer;typename N::SuccContainer;} [with N = typename std::remove_cvref<_Tp>::type::Node]' depends on itself
164 | concept StrictNodeType = requires {
| ^~~~~~~~~~
165 | typename N::PredContainer;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
166 | typename N::SuccContainer;something;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
167 | };
How is that possible?这怎么可能? Why can't GCC simply inspect the given type and check if it provides the requested subtypes?
为什么 GCC 不能简单地检查给定的类型并检查它是否提供了请求的子类型?
Here's a minimum breaking example:这是一个最小的破坏示例:
#include <type_traits>
template<typename N>
concept StrictNodeType = requires {
typename N::something;
};
template<StrictNodeType N> using Int = int;
template<int>
struct X {using type = Int<X>; };
using ThisBreaks = Int<X<0>>;
It seems there is an infinite recursion issue that constrains a concept more than it would be without it.似乎有一个无限递归问题比没有它更能限制一个概念。 I made a few changes to get more directly at the issue:
我做了一些更改以更直接地解决问题:
#include <type_traits>
template<typename N>
concept StrictNodeType = requires {
typename N::something;
};
#if 1
template<StrictNodeType N> using Int = int;
#else
template<typename N> using Int = int;
#endif
template<int>
struct X { using something = Int<X<0>>; };
using ThisBreaks=Int<X<0>>;
ThisBreaks foo()
{
return ThisBreaks{};
}
This yields the following error:这会产生以下错误:
<source>:15:37: error: template constraint failure for 'template<class N> requires StrictNodeType<N> using Int = int'
15 | struct X { using something = Int<X<0>>; };
| ^~
<source>:15:37: note: constraints not satisfied
<source>: In substitution of 'template<class N> requires StrictNodeType<N> using Int = int [with N = X<0>]':
<source>:15:37: required from here
<source>:4:9: required for the satisfaction of 'StrictNodeType<N>' [with N = X<0>]
<source>:4:26: in requirements [with N = X<0>]
<source>:5:14: note: the required type 'typename N::something' is invalid
5 | typename N::something;
| ~~~~~~~~~^~~~~~~~~~~~~
cc1plus: note: set '-fconcepts-diagnostics-depth=' to at least 2 for more detail
<source>:17:25: error: template constraint failure for 'template<class N> requires StrictNodeType<N> using Int = int'
17 | using ThisBreaks=Int<X<0>>;
| ^~
<source>:17:25: note: constraints not satisfied
<source>: In substitution of 'template<class N> requires StrictNodeType<N> using Int = int [with N = X<0>]':
<source>:17:25: required from here
<source>:4:9: required for the satisfaction of 'StrictNodeType<N>' [with N = X<0>]
<source>:4:26: in requirements [with N = X<0>]
<source>:5:14: note: the required type 'typename N::something' is invalid
5 | typename N::something;
| ~~~~~~~~~^~~~~~~~~~~~~
<source>:19:1: error: 'ThisBreaks' does not name a type
19 | ThisBreaks foo()
| ^~~~~~~~~~
Compiler returned: 1
Changing #if 1
to #if 0
compiles fine, only the Concept objects to the infinite recursion.将
#if 1
更改为#if 0
编译正常,只有 Concept 对象进行无限递归。
(Play with it here: https://godbolt.org/z/56Yd7W3sf ) (在这里玩: https : //godbolt.org/z/56Yd7W3sf )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.