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

时间:2020-10-21 15:13:46

标签: c++ c++20 c++-concepts

我正在尝试创建一个概念// these two are largely equivalent useEffect(() => stop, []) useEffect(() => { // do nothing on “mount” // return cleanup function return () => { stop() } }, []) ,该概念可以确定类型是否为嵌套范围。例如,ElementIterable中的元素是不可迭代的,但是std::vector<int>中的元素(std::vector<int>)是可迭代的。我想到了使用std::vector<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

欢迎提出所有建议。

3 个答案:

答案 0 :(得分:6)

如果您要询问类型是否为本身包含范围的范围,则只需将kubectl logs "$SOURCE_POD" -n akv2k8s-test -c istio-proxy | tail 类型应用两次:

std::range

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

答案 1 :(得分:4)

好吧,问题出在std::iterator_traits<T>上。 iterator_traits的参数应该是迭代器类型。同时,您希望该概念适用于容器。由于std::iterator_traits设计为对SFINAE友好,并且容器不太可能满足足够的旧式迭代器概念,因此在您检查概念时std::iterator_traits<T>没有成员的可能性更大。这导致该概念无法得到满足。

为什么不依赖range标头中的概念?它具有方便的实用程序来获取满足范围概念的类型的值类型

#include <ranges>

template<typename T>
concept ElementIterable = requires(std::ranges::range_value_t<T> x)
{
    x.begin();          // must have `x.begin()`
    x.end();            // and `x.end()`
};

或者,稍微更强大,并且不重塑标准特征

template<typename T>
concept ElementIterable = std::ranges::range<std::ranges::range_value_t<T>>;

答案 2 :(得分:2)

C ++ 20概念可以像您所需要的那样愚蠢(如替换文本)。在您的情况下,简单的模板鸭子类型输入应该通过检查您需要存在的内容来完成这项工作,即类型的迭代器函数结果中的迭代器函数。

考虑到这一点,您可以尝试执行以下操作:

template<typename T>
concept ElementIterable = requires(T x)
{
    x.begin()->begin();        
    x.end()->end();            
};