Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++20 Concepts: Element iterable concept

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.

like image 317
JimmyHu Avatar asked Oct 21 '20 15:10

JimmyHu


People also ask

What are concepts in c++20?

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!

What is the difference between C++11 and C++20?

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.

What is a concept in C++?

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.

What is the difference between c++20 and 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.


Video Answer


1 Answers

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.

like image 58
Nicol Bolas Avatar answered Sep 18 '22 15:09

Nicol Bolas