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.