This is a common problem of asking the wrong question of a concept, where you're trying to use them like you would a base class interface. With base classes, you're declaring the exact, specific functions that the derived classes are to implement. You want the user to implement exactly the function you say they must.
With concepts, you approach the issue from the other direction: what usage are you trying to create?
At some point in your code, you have some object, some iterator, and a size. And you're going to take that object, call a function by passing it the iterator and the size, and you expect a response back of a certain type. And this process has some meaning.
Then that is your concept. It's a concept that is based on at least 2 parameters: the type of the object and the iterator type. So that's what you should create.
If you have this BulkReadable
constraint, then you must have some interface constrained on it. An interface that's going to call read
. To call read
, that interface must have an iterator.
So here are the options:
The interface is given an iterator type (directly or indirectly) by the user. If that's the case, then you just use that type in the function's BulkReadable
constraint. If the iterator type is based on a complex set of operations on parameters, then you'll have to do some computations to compute the iterator type.
The iterator is statically determined. Then just use the known iterator type in the constraint.
The point being that, at the point where you're going to try to call read
, you know what the iterator type is. And therefore, you can constrain things using that type. Your concept therefore is not really BulkReadable
, but BulkReadableFrom
.
In short, you shouldn't want to constrain a type on being able to take any type (or any type within some constraints). Check constraints against the actual types you're going to use them with, preferably at the point where they become relevant.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…