gpt4 book ai didi

c++ - 安全地传递动态对象数组,而无需强制复制

转载 作者:行者123 更新时间:2023-12-03 07:02:02 24 4
gpt4 key购买 nike

我想定义一个函数Foo,该函数将一些对象Widget作为参数,该对象的数量仅在运行时知道。最简单的签名是:

void Foo(const std::vector<Widget>& widgets);
通过转换为模板并使用迭代器,可以使该函数更通用。但是,如果 Widget没有以某种连续的形式存储,则任何基于值数组的签名都将迫使调用者复制每个副本。例如,如果每个 Widget包含在其他某个对象 Holder中,或者如果仅需要对来自特异来源的3个小部件调用 Foo,则必须进行复制。
如果函数接受指针 vector ,则可以避免复制:
void Foo(const std::vector<const Widget*>& widgets);
但这会使功能不安全。例如:
std::vector<const Widget*> widgets;
for (const auto& holder : holders) {
widgets.push_back(&holder.get_widget());
}
Foo(widgets);
忘记 const auto&上的&符将导致段错误。
我可以想到一些安全且无复制的解决方案,其中包括lambda或 Foo模板以及自定义迭代器,但它们非常繁琐。在这种情况下最好的设计是什么?

最佳答案

The function can be made more general by turning into a template and using iterators.


这通常是一个好的设计。或者,接受通用范围。

However, if the Widgets are not stored in some contiguous form, any signature based on array-of-values would force the caller to make a copy of each.


这是使用迭代器/泛型范围而不是硬编码 vector 类型的一个很好的理由。

forgetting the ampersand on const auto& would lead to segfault.


只有幸运的时候。不能保证段故障。确实,当涉及到间接时,程序员必须小心。迭代器 vector 的另一个问题是创建新 vector 的不必要开销。

范围示例:
void Foo(const auto& widgets);

auto holder_to_widget = [](const auto& holder) {
return holder.get_widget();
};
Foo(holders | ranges::transform_view{holder_to_widget});

关于c++ - 安全地传递动态对象数组,而无需强制复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64773921/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com