Say I want to specify that an object must have a method map(...) which maps a forward_range to another (possibly different) forward_range. How can I express that in a concept?
For instance, the following struct should be accepted:
struct Mapper{
std::vector<double> map(std::list<int> args);
};
I have seen this question: C++ Concepts - Can I have a constraint requiring a function be present in a class? but I don't know how to use further concepts on argument and return types instead of using specific types.
EDIT: I have now also seen this question: How can unspecified types be used in C++20 'requires' expressions? However, it still does not help in my case. I will be more specific.
Let's assume I want to create a set of operators that operate on maps:
template<Map T1, Map T2>
class Chain {
const T1& map1;
const T2& map2;
public:
Chain(const T1& map1, const T2& map2)
:map1{ map1 }, map2{ map2 } {}
template<forward_range T>
auto map(T input) const {
return map2(map1(input));
}
};
template<Map T1, Map T2>
auto operator| (const T1& map1, const T2& map2) {
return Chain(map1, map2);
}
Now I want this operator| to only operate on objects, that have a map function which maps from an argument which is some kind of forward_range to a return value which is also some kind of forward_range.
After some research I think this is somewhat abusing concepts as interfaces which should actually be done with a Map base class. But I don't know how to define these very generic requirements on the map method there either and I also want to learn concepts.
Note that there is also this conceptual problem of inverting the strength of requirements on parameters. If the constraint semantically says "Accept objects with a map method that takes any kind of forward_range as argument and returns any kind of forward_range.", this is a very strict requirement and I don't actually need the map method to be able to handle any arbitrary kind of (i.e. all kinds of) forward_range, just that whatever kind of argument it accepts must be a kind of forward_range. (I hope this also addresses @Caleth's comment)