C++ 如何使用C++;20个概念来检查模板本身的一些约束

C++ 如何使用C++;20个概念来检查模板本身的一些约束,c++,oop,c++20,c++-concepts,C++,Oop,C++20,C++ Concepts,很抱歉标题模棱两可,我找不到合适的词来表达它。 我试图强制一个类定义一些正确的函数/运算符。例如,ForwardIterator需要有一些运算符,否则我会得到一个编译器错误。我问了这个问题,我得到了一个继承的方法,它工作得很好,但是C++20的概念似乎更直观,并且给出了更好的错误。 最初的想法是: template <typename T> concept is_ForwardIterator= requires(T x, T y) { x == y; }; template

很抱歉标题模棱两可,我找不到合适的词来表达它。 我试图强制一个类定义一些正确的函数/运算符。例如,
ForwardIterator
需要有一些运算符,否则我会得到一个编译器错误。我问了这个问题,我得到了一个继承的方法,它工作得很好,但是C++20的概念似乎更直观,并且给出了更好的错误。 最初的想法是:

template <typename T> concept is_ForwardIterator= requires(T x, T y)
{
    x == y;
};
template <typename T>
requires  is_ForwardIterator<T>
struct ForwardIterator {
};
但是编译器不断抱怨
MyCustomIterator
不满足要求:

error: constraints not satisfied for class template 'ForwardIterator' [with T = MyCustomIterator]
note: because 'MyCustomIterator' does not satisfy 'is_ForwardIterator'
template <typename T> requires is_ForwardIterator<T> struct ForwardIterator {
                               ^
note: because 'x == y' would be invalid: invalid operands to binary expression ('MyCustomIterator' and 'MyCustomIterator')
        x == y;
错误:类模板“ForwardIterator”[带有T=MyCustomIterator]的约束不满足
注意:因为“MyCustomIterator”不满足“is_ForwardIterator”
模板需要is_ForwardIterator结构ForwardIterator{
^
注意:因为'x==y'将无效:二进制表达式('MyCustomIterator'和'MyCustomIterator'的操作数无效)
x==y;

当您尝试使用CRTP时,在编译基类模板的过程中,派生类是不完整的。因此,询问有关其行为的大多数问题是不可能的。这包括使用概念的大多数原因


您尝试这样做是不合理的。您可能需要一个traits类或其他东西,这取决于您的目标。

当您尝试使用CRTP时,在编译基类模板期间,派生类是不完整的。因此,询问有关其行为的大多数问题是不可能的。这包括使用概念的理由


您试图这样做是不合理的。您可能需要一个traits类或其他东西,这取决于您的目标。

问题是,如果指定了对
ForwardIterator
的约束,则类
T
(即
MyCustomIterator
)不完整-它仅作为类名存在

您需要将约束检查延迟到
MyCustomIterator
完成之后。一种方法是:

模板
结构转发迭代器{
~ForwardIterator()需要的是_ForwardIterator{}
};

这里唯一的问题是,除非有理由实例化析构函数
~ForwardIterator
,否则不会对其进行检查,也就是说,如果您没有实际实例化
MyCustomIterator
对象,则不会对其进行检查。但实际上这不应该是一个问题。

问题在于
F指定了orwardIterator
,则类
T
(即,
MyCustomIterator
)不完整-它仅作为类名存在

您需要将约束检查延迟到
MyCustomIterator
完成之后。一种方法是:

模板
结构转发迭代器{
~ForwardIterator()需要的是_ForwardIterator{}
};

这里唯一的问题是,除非有理由实例化析构函数
~ForwardIterator
,否则不会检查它,也就是说,如果您没有实际实例化
MyCustomIterator
对象,则不会检查它。但实际上这不应该是问题。

在CRTP中,派生类不完整,因此检查ts属性是不可能的

检查traits/concept接口的一种方法是在类后简单地
static\u assert

template <typename T> concept is_ForwardIterator= requires(T x, T y)
{
    x == y;
    // ...
};

struct MyCustomIterator
{
    bool operator ==(const MyCustomIterator& other) const;
    // ...
};
static_assert(is_ForwardIterator<MyCustomIterator>);
模板概念是\u ForwardIterator=requires(T x,T y)
{
x==y;
// ...
};
结构MyCustomIterator
{
布尔运算符==(常量MyCustomIterator和其他)常量;
// ...
};
静态断言(是前向迭代器);

在CRTP中,派生类不完整,因此无法检查其属性

检查traits/concept接口的一种方法是在类后简单地
static\u assert

template <typename T> concept is_ForwardIterator= requires(T x, T y)
{
    x == y;
    // ...
};

struct MyCustomIterator
{
    bool operator ==(const MyCustomIterator& other) const;
    // ...
};
static_assert(is_ForwardIterator<MyCustomIterator>);
模板概念是\u ForwardIterator=requires(T x,T y)
{
x==y;
// ...
};
结构MyCustomIterator
{
布尔运算符==(常量MyCustomIterator和其他)常量;
// ...
};
静态断言(是前向迭代器);

ForwardIterator的目的是什么?只是一种标记和检查自定义类型是否满足约束的方法?如果是这样,如果类型必须选择此检查,为什么不能在完整的类定义之后对类型进行静态断言?
类MyCustomIterator{};静态断言(is_ForwardIterator)
您是否知道
=
重载的参数应该是
常量
引用参数,而不是可变引用参数?在类的定义中添加约束有点奇怪。通常在使用该类时,您希望检查约束。
ForwardIterator
的用途是什么>?只是标记和检查自定义类型是否满足约束的一种方法?如果是这样,如果类型必须选择此检查,为什么不能在完整的类定义之后对类型进行静态断言?
class MyCustomIterator{};static\u assert(is\u ForwardIterator)
您是否知道
=
重载的参数应该是
常量
引用参数,而不是可变引用参数?在类的定义中添加约束有点奇怪。通常在使用类时,您会希望检查约束。
template <typename T> concept is_ForwardIterator= requires(T x, T y)
{
    x == y;
    // ...
};

struct MyCustomIterator
{
    bool operator ==(const MyCustomIterator& other) const;
    // ...
};
static_assert(is_ForwardIterator<MyCustomIterator>);