Issue
In the following concept implementation struct, String, the operator() method does not take the value Source by reference but still satisfies the concept Consumer. How can I prevent String from being a valid Consumer, specifically by requiring Source source to be a reference &?
template <class Type, class Source>
concept Consumer = requires(Type type, Source & source, std::ranges::iterator_t<Source> position) {
{ type.operator()(source, position) } -> std::same_as<Source>;
};
struct String {
public:
std::string operator()(const std::string source, std::string::const_iterator position) {
return "test";
}
};
int main(const int, const char * []) {
String consumer{};
static_assert(Consumer<String, std::string>);
auto test = std::string("test");
consumer(test, std::begin(test));
}
Solution
You cannot (reasonably) detect if takes a reference parameter. But you can detect if it can take an rvalue:
template <class Type, class Source>
concept ConsumerOfRvalue = requires(Type type, Source &&source, std::ranges::iterator_t<Source> position) {
type(std::move(source), position);
};
If the function takes its parameter by &&, by const&, or by value (assuming Source is moveable), then it will satisfy ConsumerOfRvalue. Therefore, you can make your Consumer require that the types not satisfy ConsumerOfRvalue:
template <class Type, class Source>
concept Consumer = !ConsumerOfRvalue<Type, Source> &&
requires(Type type, Source & source, std::ranges::iterator_t<Source> position) {
{ type(source, position) } -> std::same_as<Source>;
};
Answered By - Nicol Bolas Answer Checked By - Marie Seifert (PHPFixing Admin)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.