需要以 OutputIterator 作为参数的成员函数的 C++ 概念
C++ Concept that requires a member function with an OutputIterator as parameter
我在玩弄概念,遇到了障碍。又或许只是我脑子有问题
我想创建一个 class 来缓冲 "bulk-readable" 数据源。这样的数据源应该有一个成员函数,它接受一个 OutputIterator 并有一个像这样的签名:
template<typename It>
size_t read(It firstItem, size_t max)
我的想法是定义一个类似于 BulkReadable
的概念:
template<typename Source>
concept bool BulkReadable =
requires(Source s, Iter out, size_t max) {
{s.read(out, max)} -> size_t;
};
我在指定 Iter
时遇到问题。我可以在模板参数列表中添加另一个类型名称,但是想要使用该概念的 Buffer class 需要指定该参数的类型。
我想使用这个概念的理想方式是:
template<BulkReadable Source>
class Buffer {
public:
Source& input:
Buffer(Source& input) : input(input){}
...
这种方法是否可行?如果是,如果我不 want/can 指定类型,我如何要求模板化方法签名?
这是一个常见的问题,即提出错误的概念问题,您尝试像使用基础 class 界面一样使用它们。使用基础 classes,您要声明派生的 classes 要实现的确切、特定的功能。您希望用户准确地实现您所说的他们必须执行的功能。
通过概念,您可以从另一个方向处理问题:您要创建什么用法?
在您的代码中的某个时刻,您有一些对象、一些迭代器和一个大小。您将获取该对象,通过将迭代器和大小传递给它来调用一个函数,并且您期望返回某种类型的响应。而这个过程是有一定意义的。
那么那个就是你的概念。这是一个基于至少两个参数的概念:对象的类型和迭代器类型。所以这就是你应该创造的。
如果你有这个BulkReadable
约束,那么你必须有一些接口约束它。将要调用 read
的接口。要调用 read
,该接口必须有一个迭代器。
以下是选项:
接口由用户(直接或间接)指定了一个迭代器类型。如果是这种情况,那么您只需在函数的 BulkReadable
约束中使用该类型。如果迭代器类型基于一组复杂的参数操作,那么您将不得不进行一些计算来计算迭代器类型。
迭代器是静态确定的。然后在约束中使用已知的迭代器类型。
重点在于,在您尝试调用 read
时,您 知道 迭代器类型是什么。因此,您可以使用该类型来约束事物。因此,您的概念实际上并不是 BulkReadable
,而是 BulkReadableFrom
.
简而言之,您不应该限制类型能够采用任何类型(或某些约束内的任何类型)。针对您要使用它们的实际类型检查约束,最好是在它们变得相关的时候。
我在玩弄概念,遇到了障碍。又或许只是我脑子有问题
我想创建一个 class 来缓冲 "bulk-readable" 数据源。这样的数据源应该有一个成员函数,它接受一个 OutputIterator 并有一个像这样的签名:
template<typename It>
size_t read(It firstItem, size_t max)
我的想法是定义一个类似于 BulkReadable
的概念:
template<typename Source>
concept bool BulkReadable =
requires(Source s, Iter out, size_t max) {
{s.read(out, max)} -> size_t;
};
我在指定 Iter
时遇到问题。我可以在模板参数列表中添加另一个类型名称,但是想要使用该概念的 Buffer class 需要指定该参数的类型。
我想使用这个概念的理想方式是:
template<BulkReadable Source>
class Buffer {
public:
Source& input:
Buffer(Source& input) : input(input){}
...
这种方法是否可行?如果是,如果我不 want/can 指定类型,我如何要求模板化方法签名?
这是一个常见的问题,即提出错误的概念问题,您尝试像使用基础 class 界面一样使用它们。使用基础 classes,您要声明派生的 classes 要实现的确切、特定的功能。您希望用户准确地实现您所说的他们必须执行的功能。
通过概念,您可以从另一个方向处理问题:您要创建什么用法?
在您的代码中的某个时刻,您有一些对象、一些迭代器和一个大小。您将获取该对象,通过将迭代器和大小传递给它来调用一个函数,并且您期望返回某种类型的响应。而这个过程是有一定意义的。
那么那个就是你的概念。这是一个基于至少两个参数的概念:对象的类型和迭代器类型。所以这就是你应该创造的。
如果你有这个BulkReadable
约束,那么你必须有一些接口约束它。将要调用 read
的接口。要调用 read
,该接口必须有一个迭代器。
以下是选项:
接口由用户(直接或间接)指定了一个迭代器类型。如果是这种情况,那么您只需在函数的
BulkReadable
约束中使用该类型。如果迭代器类型基于一组复杂的参数操作,那么您将不得不进行一些计算来计算迭代器类型。迭代器是静态确定的。然后在约束中使用已知的迭代器类型。
重点在于,在您尝试调用 read
时,您 知道 迭代器类型是什么。因此,您可以使用该类型来约束事物。因此,您的概念实际上并不是 BulkReadable
,而是 BulkReadableFrom
.
简而言之,您不应该限制类型能够采用任何类型(或某些约束内的任何类型)。针对您要使用它们的实际类型检查约束,最好是在它们变得相关的时候。