I have the following code at the moment:
#include <iterator>
#include <vector>
struct bar{};
struct details {};
struct foo {
details det;
std::vector<bar> data;
};
template <std::input_iterator Iter>
foo create_foo(const details& details, Iter begin, Iter end) {
return foo {
.det = details,
.data = {begin, end}
};
}
int main() {
std::vector<bar> bars = {bar{},bar{},bar{}};
create_foo({}, bars.begin(), bars.end());
return 0;
}
foo::data
is a Container for bar
s. It's constructor takes two Iterators.
I want to constrain the input iterators to be iterators of containers containing bar
only, e.g. a std::vector<bar>::iterator
or a std::list<bar>::iterator
How would I achieve this with concepts?
You can add a requires
clause to create_foo
:
template <std::input_iterator Iter>
foo create_foo(const details& details, Iter begin, Iter end)
requires std::is_same_v<typename Iter::value_type, bar>
{
// ...
}
As @StoryTeller-UnslanderMonica commented, using std::same_as
and std::iter_value_t
for the requires
clause will improve it and support pointers and a wider range of containers:
template <std::input_iterator Iter>
foo create_foo(const details& details, Iter begin, Iter end)
requires std::same_as<std::iter_value_t<Iter>, bar>
{
// ...
}