I am trying to create a concept ElementIterable
which can determine the type is nested ranges or not. For example, the elements in std::vector<int>
is not iterable, but the elements (std::vector<int>
) in std::vector<std::vector<int>>
is iterable. The idea about using std::iterator_traits<T>
comes up in my mind and the experimental code is as following. However, this ElementIterable
concept doesn't work as the expected behavior. Is there any idea to fix this ElementIterable
concept?
template<typename T>
concept ElementIterable = requires(typename std::iterator_traits<T>::value_type x) // requires-expression
{
x.begin(); // must have `x.begin()`
x.end(); // and `x.end()`
};
The usage of this ElementIterable
is here.
template<typename T> requires ElementIterable<T>
void Foo(T input);
template<typename T> requires ElementIterable<T>
void Foo(T input)
{
std::cout << "Element iterable" << std::endl;
}
template<typename T>
void Foo(T input);
template<typename T>
void Foo(T input)
{
std::cout << "Element not iterable" << std::endl;
}
The usage of the function Foo
.
int number = 1;
std::vector<decltype(number)> vector1;
vector1.push_back(number);
Foo(vector1); // Element not iterable
std::vector<decltype(vector1)> vector2;
vector2.push_back(vector1);
Foo(vector2); // Element not iterable
// but expected behaviour is: Element iterable
All suggestions are welcome.
C++20 Concepts - a Quick Introduction Concepts are a revolutionary approach for writing templates! They allow you to put constraints on template parameters that improve the readability of code, speed up compilation time, and give better error messages. Read on and learn how to use them in your code!
With C++20, you can use a constrained placeholder (concept) in each place you could use an unconstrained placeholder ( auto) in C++11. But this is not the end of the unification. Defining a template becomes with C++20 a piece of cake. Just use a constrained or an unconstrained placeholder in the declaration of a function.
In short, a concept is a set of constraints on template parameters evaluated at compile time. You can use them for class templates and function templates to control function overloads and partial specialization. C++20 gives us language support (new keywords - requires, concept) and a set of predefined concepts from the Standard Library.
Additionally, the Standard Library is equipped with a set of predefined concepts (mainly obtained from existing type traits), making it easier to start. What’s more, C++20 offers even more language features to make the syntax even more compact.
If you want to ask if a type is a range which itself contains a range, that's simply applying the std::range
type twice:
template<typename T>
concept nested_range = std::ranges::range<T> && std::ranges::range<std::ranges::range_value_t<T>>
range_value_t
extracts the value_type
from the iterator type of the range. Here's a live example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With