C++20概念:元素可迭代概念

2022-05-16 00:00:00 c++ c++20 c++-concepts

我正在尝试创建一个概念ElementIterable,它可以确定类型是否为嵌套区域。例如,std::vector<int>中的元素是不可迭代的,但std::vector<std::vector<int>>中的元素(std::vector<int>)是可迭代的。关于使用std::iterator_traits<T>的想法出现在我的脑海中,实验代码如下所示。然而,这个ElementIterable概念并不像预期的那样工作。是否有解决此ElementIterable概念的方法?

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()`
};

这里是ElementIterable的用法。

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;
}

函数的用法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

欢迎所有建议。


解决方案

如果您想问一个类型是否是本身包含范围的范围,只需将std::range类型应用两次:

template<typename T>
concept nested_range = std::ranges::range<T> && std::ranges::range<std::ranges::range_value_t<T>>
range_value_t从范围的迭代器类型中提取value_type。Here's a live example。

相关文章