标准库中有许多用例,我遇到了自己的代码,在这种情况下,我希望传递输入和输出范围必须相同,通常是某种算法。目前这需要三个,或四个如果你要小心,迭代器。通常会有一堆检查以确保迭代器有意义。
我知道在某些情况下,array_view可能会合并成对/结束迭代器对,但仍然需要检查输入和输出array_views可能是不同的大小。是否有关于类的讨论包含输入和输出范围规范?也许范围提案解决了部分或全部这一点,但我不清楚它是如何做的。
答案 0 :(得分:0)
我经常有类似的用例。我发现最通用的方法是将引用传递给输出'容器'概念而不是范围或迭代器对。然后算法可以根据需要自由调整大小或扩展容器,缓冲区溢出的可能性消失。
(一个简单的人为设计)例子,如:
template<class InputIter, class OutputContainer>
void encrypt_to(OutputContainer& dest, InputIter first, InputIter last)
{
dest.resize(last - first);
// ... todo: replace this with some actual encryption
std::copy(first, last, dest.begin());
}
对于我想隐藏实现的函数,我有一个表示目标容器的抽象接口。它需要虚拟begin()
,end()
和resize()
方法。
例如:
#include <iostream>
#include <algorithm>
#include <vector>
struct mutable_byte_buffer_concept {
using iterator=uint8_t*;
virtual iterator begin() = 0;
virtual iterator end() = 0;
virtual void resize(size_t newsize) = 0;
// note : no virtual destructor - by design.
};
template<class Container>
struct mutable_byte_buffer_model : mutable_byte_buffer_concept
{
mutable_byte_buffer_model(Container& container)
: container(container)
{
}
virtual iterator begin() override
{
return reinterpret_cast<iterator>(&container[0]);
}
virtual iterator end() override
{
return reinterpret_cast<iterator>(&container[0]) + container.size();
}
virtual void resize(size_t newsize) override
{
container.resize(newsize);
}
Container& container;
};
template<class Container>
auto make_mutable_buffer(Container& c)
-> mutable_byte_buffer_model<Container>
{
return { c };
}
// note: accepting an rvalue allows me to use polymorphism at the call site without needing any memory allocation
template<class Iter>
void copy_to(mutable_byte_buffer_concept&& dest, Iter first, Iter last)
{
dest.resize(last - first);
std::copy(first, last, dest.begin());
}
using namespace std;
auto main() -> int
{
auto a = "Hello, World"s;
string b;
vector<uint8_t> c;
string d;
copy_to(make_mutable_buffer(b), begin(a), end(a));
copy_to(make_mutable_buffer(c), begin(b), end(b));
copy_to(make_mutable_buffer(d), begin(c), end(c));
cout << d << endl;
return 0;
}