C++ C++;20个概念:元素可替换概念
我正在尝试创建一个概念C++ C++;20个概念:元素可替换概念,c++,c++20,c++-concepts,C++,C++20,C++ Concepts,我正在尝试创建一个概念ElementIterable,它可以确定类型是否为嵌套范围。例如,std::vector中的元素是不可编辑的,但是std::vector中的元素(std::vector)是可编辑的。我想到了使用std::iterator_traits的想法,实验代码如下。但是,此ElementIterable概念不能像预期的行为那样工作。有没有办法解决这个ElementIterable概念 template<typename T> concept ElementIterabl
ElementIterable
,它可以确定类型是否为嵌套范围。例如,std::vector
中的元素是不可编辑的,但是std::vector
中的元素(std::vector
)是可编辑的。我想到了使用std::iterator_traits
的想法,实验代码如下。但是,此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()`
};
函数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
int number=1;
std::矢量1;
矢量1.推回(数字);
Foo(向量1);//元素不可分
std::矢量2;
矢量2.推回(矢量1);
Foo(矢量2);//元素不可分
//但预期的行为是:元素不可预测
欢迎提出所有建议。C++20概念可以根据您的需要而变得愚蠢(例如,文本替换)。在您的情况下,简单模板duck类型应该通过检查您需要存在的内容来完成这项工作,即在您的类型的迭代器函数的结果中检查迭代器函数 考虑到这一点,您可以尝试以下方式:
template<typename T>
concept ElementIterable = requires(T x)
{
x.begin()->begin();
x.end()->end();
};
模板
概念元素iterable=requires(T x)
{
x、 begin()->begin();
x、 end()->end();
};
问题是std::iterator\u traits
。iterator\u traits
的参数应该是迭代器类型。同时,您希望该概念适用于容器。由于std::iterator_traits
设计为对SFINAE友好,而且容器不太可能满足足够的旧迭代器概念,因此在检查概念时,很可能std::iterator_traits
没有成员。这导致概念没有得到满足
为什么不依赖范围标题中的概念?它有一个方便的实用程序来获取满足范围概念的类型的值类型
#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()`
};
#包括
模板
概念元素iterable=requires(标准::范围::范围\u值\u t x)
{
x、 begin();//必须有'x.begin()`
x、 end();//和'x.end()`
};
或者,稍微强健一些,不需要重塑标准特征
template<typename T>
concept ElementIterable = std::ranges::range<std::ranges::range_value_t<T>>;
模板
概念元素iterable=std::ranges::range;
如果要询问某个类型是否是一个本身包含范围的范围,只需将std::range
类型应用两次:
template<typename T>
concept nested_range = std::ranges::range<T> && std::ranges::range<std::ranges::range_value_t<T>>
模板
概念嵌套_range=std::ranges::range&&std::ranges::range
range\u value\u t
从范围的迭代器类型中提取value\u type
为什么不在类型本身上检查v.begin()->begin()
和v.end()->end()
?是的,修复了它,这是复制提供的代码后留下的。这是一个非常糟糕的概念。它不使用任何现有的标准库概念,因此不能包含它们。它只检查memberwisebegin/end
,而不是允许其他内容的ranges::begin/end
。总的来说,这不是解决问题的好方法。感谢您解释std::iterator\u traits
无法生效的原因。
template<typename T>
concept nested_range = std::ranges::range<T> && std::ranges::range<std::ranges::range_value_t<T>>