C++ 是否有任何快速方法来检测有多少 std::vector 个元素已被 updated/modified?
C++ Is there any fast way to detect how many std::vector elements has been updated/modified?
我目前正在实现一个缓存系统,它具有与 std::vector
类似的 API,但它有一个名为 Flush
的成员函数,用于将元素传输到某个地方(例如硬件、网络等)。
我想做的是让缓存系统能够通过刷新最小化传输开销,只传输修改后的元素而不是整个数组,而且传输频率应该受到限制,因为它需要启动传输的时间成本。
我尝试做的是继承std::vector
,然后尝试找出是否有像on_element_modified
或on_element_updated
这样的接口供我用来检测是否用户修改了任何元素(通过 operator[]
、迭代器或 push_back
insert
remove
等)然后在刷新时,我可以只传输这些修改的元素,但是看起来 std::vector
没有这样的接口供我使用。
template<typename Ty, typename Allocator = std::allocator<Ty>>
class MyFlushableVector : public std::vector
{
protected:
using size_type = typename std::vector::size_type;
std::vector<bool> updated;
// These imagined functions is what I need
void on_element_modified(size_type index) override
{
updated[index] = true;
}
void on_new_element() override
{
updated.push_back(true);
}
void on_popped_element() override
{
updated.pop_back();
}
void Transfer(Ty *Pointer, size_type count)
{
// Do some transfer
}
public:
void Flush()
{
// Minimize the frequency of transfer by finding the updated blocks to transfer.
size_type i, first_updated = 0;
bool is_modified = false;
for (i = 0; i < size(); i++)
{
if (is_modified == false)
{
if (updated[i])
{
first_updated = i;
is_modified = true;
}
}
else
{
if (!updated[i])
{
Transfer(data() + first_updated, i - first_updated);
is_modified = false;
}
}
updated[i] = false;
}
if (is_modified)
{
Transfer(data() + first_updated, i - first_updated);
}
}
};
因为我找不到这些想象中的接口来使用,我现在正在尝试实现一个新的 class,它不是从 std::vector
继承的,但它具有与 std::vector
我实现了它们中的每一个,除了它不支持迭代器(因为我不知道如何实现一个迭代器来检测对向量的任何写操作并将相应的 updated
元素设置为 true ).我不确定这是在现代 C++ 中实现它的真正方法。
这个问题的标题中包含的问题的简短答案是“否”,在 vector
和任何其他 C++ 库容器中都没有。如果您需要跟踪容器中值的更改,则需要您实施整个脚手架。
除此之外,您似乎间接问的唯一一件事是在最后一段中,我将在我的其余回答中解决:
I don't know how to implement an iterator that can detect any
write operations to the vector and set the corresponding updated
element to true)
我想您是在问如何做到这一点。好吧,您可以使用 std::ostreambuf_iterator
已经在 C++ 库中使用的相同方法,您可以简单地将其用于您自己的目的。
std::ostreambuf_iterator<char> iter{std::cout};
*iter++ = 'H';
*iter++ = 'e';
// and so on, for the remainder of "Hello world!", which will get written
// to C++
这里的关键因素是迭代器不是指针。它们只是 objects 实现了 *
和其他几个运算符(取决于迭代器声明类别的要求)。
std::ostreambuf_iterator
实现了 *
和 ++
运算符,它们什么都不做。他们 return 迭代器本身。然后,std::ostreambuf_iterator
还实现了 =
运算符,它接受给定的 char
,并将其写入输出流缓冲区。
所以,表达式*iter++
是一个big-fat-nothing,它只是为了满足这个迭代器类别的要求而存在的,所有的动作都发生在=
运算符重载中。 *iter++='H';
只有实际发生的工作是在调用的 operator=
重载中。
您的自定义迭代器 class 只需要做同样的事情:实现 operator Ty
和 operator=(const Ty&)
。前者移交迭代器引用的实际 Ty
值。后者为其赋新值,然后设置相应的modified
标志位。您的容器移交这些迭代器,以对其进行迭代。结束。任务完成。
我目前正在实现一个缓存系统,它具有与 std::vector
类似的 API,但它有一个名为 Flush
的成员函数,用于将元素传输到某个地方(例如硬件、网络等)。
我想做的是让缓存系统能够通过刷新最小化传输开销,只传输修改后的元素而不是整个数组,而且传输频率应该受到限制,因为它需要启动传输的时间成本。
我尝试做的是继承std::vector
,然后尝试找出是否有像on_element_modified
或on_element_updated
这样的接口供我用来检测是否用户修改了任何元素(通过 operator[]
、迭代器或 push_back
insert
remove
等)然后在刷新时,我可以只传输这些修改的元素,但是看起来 std::vector
没有这样的接口供我使用。
template<typename Ty, typename Allocator = std::allocator<Ty>>
class MyFlushableVector : public std::vector
{
protected:
using size_type = typename std::vector::size_type;
std::vector<bool> updated;
// These imagined functions is what I need
void on_element_modified(size_type index) override
{
updated[index] = true;
}
void on_new_element() override
{
updated.push_back(true);
}
void on_popped_element() override
{
updated.pop_back();
}
void Transfer(Ty *Pointer, size_type count)
{
// Do some transfer
}
public:
void Flush()
{
// Minimize the frequency of transfer by finding the updated blocks to transfer.
size_type i, first_updated = 0;
bool is_modified = false;
for (i = 0; i < size(); i++)
{
if (is_modified == false)
{
if (updated[i])
{
first_updated = i;
is_modified = true;
}
}
else
{
if (!updated[i])
{
Transfer(data() + first_updated, i - first_updated);
is_modified = false;
}
}
updated[i] = false;
}
if (is_modified)
{
Transfer(data() + first_updated, i - first_updated);
}
}
};
因为我找不到这些想象中的接口来使用,我现在正在尝试实现一个新的 class,它不是从 std::vector
继承的,但它具有与 std::vector
我实现了它们中的每一个,除了它不支持迭代器(因为我不知道如何实现一个迭代器来检测对向量的任何写操作并将相应的 updated
元素设置为 true ).我不确定这是在现代 C++ 中实现它的真正方法。
这个问题的标题中包含的问题的简短答案是“否”,在 vector
和任何其他 C++ 库容器中都没有。如果您需要跟踪容器中值的更改,则需要您实施整个脚手架。
除此之外,您似乎间接问的唯一一件事是在最后一段中,我将在我的其余回答中解决:
I don't know how to implement an iterator that can detect any write operations to the vector and set the corresponding
updated
element to true)
我想您是在问如何做到这一点。好吧,您可以使用 std::ostreambuf_iterator
已经在 C++ 库中使用的相同方法,您可以简单地将其用于您自己的目的。
std::ostreambuf_iterator<char> iter{std::cout};
*iter++ = 'H';
*iter++ = 'e';
// and so on, for the remainder of "Hello world!", which will get written
// to C++
这里的关键因素是迭代器不是指针。它们只是 objects 实现了 *
和其他几个运算符(取决于迭代器声明类别的要求)。
std::ostreambuf_iterator
实现了 *
和 ++
运算符,它们什么都不做。他们 return 迭代器本身。然后,std::ostreambuf_iterator
还实现了 =
运算符,它接受给定的 char
,并将其写入输出流缓冲区。
所以,表达式*iter++
是一个big-fat-nothing,它只是为了满足这个迭代器类别的要求而存在的,所有的动作都发生在=
运算符重载中。 *iter++='H';
只有实际发生的工作是在调用的 operator=
重载中。
您的自定义迭代器 class 只需要做同样的事情:实现 operator Ty
和 operator=(const Ty&)
。前者移交迭代器引用的实际 Ty
值。后者为其赋新值,然后设置相应的modified
标志位。您的容器移交这些迭代器,以对其进行迭代。结束。任务完成。