- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在尝试编写一个带有自己的迭代器的自定义容器,该迭代器可用作范围并与 std::span
一起使用。我是范围的新手,所以请客气。
以下示例编译失败,因为我的容器类无法转换为 std::span
#include<span>
#include<vector>
#include<cstdint>
template<class T, class Allocator = std::allocator<T>>
class MyContainer
{
public:
class ConstIterator
{
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using difference_type = size_t;
using pointer = T* const;
using reference = const T&;
ConstIterator() = default;
ConstIterator(const ConstIterator &other) = default;
ConstIterator(pointer ptr)
: m_ptr(ptr)
{}
reference operator*() const
{
return *m_ptr;
}
pointer operator->()
{
return m_ptr;
}
// Prefix increment
ConstIterator& operator++()
{
m_ptr++;
return *this;
}
// Postfix increment
ConstIterator operator++(int)
{
Iterator tmp = *this;
++(*this);
return tmp;
}
// Prefix decrement
ConstIterator& operator--()
{
m_ptr--;
return *this;
}
// Postfix decrement
ConstIterator operator--(int)
{
Iterator tmp = *this;
--(*this);
return tmp;
}
ConstIterator& operator+=(const difference_type offset) noexcept
{
m_ptr += offset;
return *this;
}
ConstIterator operator+(const difference_type offset) const noexcept
{
ConstIterator tmp = *this;
tmp += offset;
return tmp;
}
ConstIterator& operator-=(const difference_type offset) noexcept
{
return *this += -offset;
}
ConstIterator operator-(const difference_type offset) const noexcept
{
ConstIterator tmp = *this;
tmp -= offset;
return tmp;
}
difference_type operator-(const ConstIterator& right) const noexcept
{
compatible(right);
return m_ptr - right.m_ptr;
}
reference operator[](const difference_type offset) const noexcept
{
return *(*this + offset);
}
bool operator==(const ConstIterator& right) const noexcept
{
return (*this == right);
}
bool operator!=(const ConstIterator& right) const noexcept
{
return !(*this == right);
}
bool operator<(const ConstIterator& right) const noexcept
{
compatible(right);
return m_ptr < right.m_ptr;
}
bool operator>(const ConstIterator& right) const noexcept
{
return right < *this;
}
bool operator<=(const ConstIterator& right) const noexcept
{
return !(right < *this);
}
bool operator>=(const ConstIterator& right) const noexcept
{
return !(*this < right);
}
protected:
T* m_ptr;
};
class Iterator : public ConstIterator
{
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using difference_type = size_t;
using pointer = T*;
using reference = T&;
Iterator() = default;
Iterator(const Iterator &other) = default;
Iterator(pointer ptr)
: ConstIterator(ptr)
{}
reference operator*() const
{
return *ConstIterator::m_ptr;
}
pointer operator->()
{
return ConstIterator::m_ptr;
}
// Prefix increment
Iterator& operator++()
{
ConstIterator::m_ptr++;
return *this;
}
// Postfix increment
Iterator operator++(int)
{
Iterator tmp = *this;
++(*this);
return tmp;
}
// Prefix decrement
Iterator& operator--()
{
ConstIterator::m_ptr--;
return *this;
}
// Postfix decrement
Iterator operator--(int)
{
Iterator tmp = *this;
--(*this);
return tmp;
}
Iterator& operator+=(const difference_type offset) noexcept
{
ConstIterator::_Verify_offset(offset);
ConstIterator::m_ptr += offset;
return *this;
}
Iterator operator+(const difference_type offset) const noexcept
{
Iterator tmp = *this;
tmp += offset;
return tmp;
}
Iterator& operator-=(const difference_type offset) noexcept
{
return *this += -offset;
}
Iterator operator-(const difference_type offset) const noexcept
{
Iterator tmp = *this;
tmp -= offset;
return tmp;
}
difference_type operator-(const ConstIterator& right) const noexcept
{
compatible(right);
return ConstIterator::m_ptr - right.m_ptr;
}
reference operator[](const difference_type offset) const noexcept
{
return *(*this + offset);
}
};
public:
using value_type = T;
using allocator_type = Allocator;
using pointer = typename std::allocator_traits<Allocator>::pointer;
using const_pointer = typename std::allocator_traits<Allocator>::const_pointer;
using reference = value_type &;
using const_reference = const value_type &;
using size_type = typename std::vector<T>::size_type;
using difference_type = typename std::vector<T>::difference_type;
using iterator = Iterator;
using const_iterator = ConstIterator;
using reverse_iterator = typename std::reverse_iterator<iterator>;
using const_reverse_iterator = typename std::reverse_iterator<const_iterator>;
MyContainer()
{
m_data.resize(10);
}
iterator begin()
{
return iterator(&m_data[0]);
}
iterator end()
{
return iterator(&m_data[0]+m_data.size());
}
const_iterator begin() const
{
return const_iterator(&m_data[0]);
}
const_iterator end() const
{
return const_iterator(&m_data[0]+m_data.size());
}
/*
//These versions of begin() and end() work
T* begin()
{
return &m_data[0];
}
T* end()
{
return &m_data[0]+m_data.size();
}
T* const begin() const
{
return &m_data[0];
}
T* const end() const
{
return &m_data[0]+m_data.size();
}*/
private:
std::vector<value_type> m_data;
};
int getSum(std::span<int const>s)
{
int result =0;
for (int val : s)
result += val;
return result;
}
int main()
{
MyContainer<int> data;
int sum = getSum(data);
}
抱歉,这是一个很长的最小示例,但我的理解是自定义迭代器需要提供所有适当的功能才能与 std::span
一起使用。
我从 clang 得到的编译错误是
<source>:282:12: error: no matching function for call to 'getSum'
int sum = getSum(data);
^~~~~~
<source>:271:5: note: candidate function not viable: no known conversion from 'MyContainer<int>' to 'std::span<const int>' for 1st argument
int getSum(std::span<int const>s)
^
1 error generated.
或者来自VS2019
<source>(282): error C2664: 'int getSum(std::span<const int,18446744073709551615>)': cannot convert argument 1 from 'MyContainer<int,std::allocator<int>>' to 'std::span<const int,18446744073709551615>'
<source>(282): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
<source>(271): note: see declaration of 'getSum'
Clang 最初给我的错误是不满足所有各种范围类型的要求,包括输入和输出范围,它引用了 _Begin。但是当我将代码剥离回这个示例时,消息变得不那么详细了。
这让我觉得我的迭代器有问题。如果我不返回我的自定义迭代器,而是只返回一个原始指针,那么代码可以正常编译。
有什么方法可以解决我的代码无法正常工作的原因吗?我什至在努力寻找一个适合新手理解的所有这一切的指南。
最佳答案
对于以后再做的任何人,我调试迭代器的方法是设置一组静态断言来检查我的迭代器在哪个点不符合要求。因为迭代器类型形成了一个层次结构,其中每个迭代器还必须满足层次结构中更下方的迭代器的要求(除了同等的输入和输出),我从
using cType = sci::MyContainer<int>;
using iType = cType::Iterator;
static_assert(std::input_iterator<iType>, "failed input iterator");
static_assert(std::output_iterator<iType, int>, "failed output iterator");
static_assert(std::forward_iterator<iType>, "failed forward iterator");
static_assert(std::input_iterator<iType>, "failed input iterator");
static_assert(std::bidirectional_iterator<iType>, "failed bidirectional iterator");
static_assert(std::random_access_iterator<iType>, "failed random access iterator");
static_assert(std::contiguous_iterator<iType>, "failed contiguous iterator");
然后我从第一个错误开始,找到该概念的代码并为子概念设置 static_assert
。例如,当我收到“输入迭代器失败”错误时,我设置了静态断言
static_assert(std::weakly_incrementable<iType>, "Failed the weakly incrementable test");
static_assert(std::movable<iType>, "Failed the moveable test");
static_assert(std::default_initializable<iType>, "Failed the default initializable test");
这让我发现(如@Unslander Monica 所述)我有一个未签名的 difference_type
当它需要被签名时,我没有 Iterator operator+(const difference_type offset, const Iterator &iter)
,我需要一个 element_type
,对于我的非 const
迭代器,我需要一个 const pointer operator->() const
。
关于c++ - 无法满足 C++ 范围要求自定义容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69254654/
我不能解决这个问题。和标题说的差不多…… 如果其他两个范围/列中有“否”,我如何获得范围或列的平均值? 换句话说,我想计算 A 列的平均值,并且我有两列询问是/否问题(B 列和 C 列)。我只希望 B
我知道 python 2to3 将所有 xrange 更改为 range 我没有发现任何问题。我的问题是关于它如何将 range(...) 更改为 list(range(...)) :它是愚蠢的,只是
我有一个 Primefaces JSF 项目,并且我的 Bean 注释有以下内容: @Named("reportTabBean") @SessionScoped public class Report
在 rails3 中,我在模型中制作了相同的范围。例如 class Common ?" , at) } end 我想将公共(public)范围拆分为 lib 中的模块。所以我试试这个。 module
我需要在另一个 View 范围 bean 中使用保存在 View 范围 bean 中的一些数据。 @ManagedBean @ViewScoped public class Attivita impl
为什么下面的代码输出4?谁能给我推荐一篇好文章来深入学习 javascript 范围。 这段代码返回4,但我不明白为什么? (function f(){ return f(); functio
我有一个与此结构类似的脚本 $(function(){ var someVariable; function doSomething(){ //here } $('#som
我刚刚开始学习 Jquery,但这些示例对我帮助不大...... 现在,以下代码发生的情况是,我有 4 个表单,我使用每个表单的链接在它们之间进行切换。但我不知道如何在第一个函数中获取变量“postO
为什么当我这样做时: function Dog(){ this.firstName = 'scrappy'; } Dog.firstName 未定义? 但是我可以这样做: Dog.firstNa
我想打印文本文件 text.txt 的选定部分,其中包含: tickme 1.1(no.3) lesson1-bases lesson2-advancedfurther para:using the
我正在编写一些 JavaScript 代码。我对这个关键字有点困惑。如何在 dataReceivedHandler 函数中访问 logger 变量? MyClass: { logger: nu
我有这个代码: Public Sub test() Dim Tgt As Range Set Tgt = Range("A1") End Sub 我想更改当前为“A1”的 Tgt 的引
我正忙于此工作,以为我会把它放在我们那里。 该数字必须是最多3个单位和最多5个小数位的数字,等等。 有效的 999.99999 99.9 9 0.99999 0 无效的 -0.1 999.123456
覆盖代码时: @Override public void open(ExecutionContext executionContext) { super.open(executio
我想使用 preg_match 来匹配数字 1 - 21。我如何使用 preg_match 来做到这一点?如果数字大于 21,我不想匹配任何东西。 example preg_match('([0-9]
根据docs range函数有四种形式: (range) 0 - 无穷大 (range end) 0 - 结束 (range start end)开始 - 结束 (range start end st
我知道有一个UISlider,但是有人已经制作了RangeSlider(用两个拇指吗?)或者知道如何扩展 uislider? 最佳答案 我认为你不能直接扩展 UISlider,你可能需要扩展 UICo
我正在尝试将范围转换为列表。 nums = [] for x in range (9000, 9004): nums.append(x) print nums 输出 [9000] [9
请注意:此问题是由于在运行我的修饰方法时使用了GraphQL解析器。这意味着this的范围为undefined。但是,该问题的基础知识对于装饰者遇到问题的任何人都是有用的。 这是我想使用的基本装饰器(
我正在尝试创建一个工具来从网页上抓取信息(是的,我有权限)。 到目前为止,我一直在使用 Node.js 结合 requests 和 Cheerio 来拉取页面,然后根据 CSS 选择器查找信息。我已经
我是一名优秀的程序员,十分优秀!