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

标签 c++

我想定义一个函数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/

相关文章:

c++ - 使用 FFmpeg 的音频均衡器

c++ - 为什么我可以改变 const 对象中的成员变量,这是返回 const 对象函数的结果?

c++ - 升级到 OS X Mavericks 后架构 x86_64 的 OpenCV undefined symbol

c++ - 不需要安装运行时/依赖项的编程语言

c++ - 将 QFileDialog 与 QWindow 一起使用

c++ - 转换日期格式 Www Mmm dd hh :mm:ss yyyy to dd hh:mm:ss string in c++

c# - 从 c# 调用的 c++ dll 导出函数返回字符串

c++ - 矩阵乘法作为列专业

c++ - 提升精神报告语义错误

c++ - 重复调用的函数中的静态常量与常量