将元素的向量转换为另一个元素的向量,而无需初始化后者
我有一个const std :: vector< t>源
大小的和std :: vector< t> dest
。 我想将转换应用于source
中的每个元素,然后将其存储在dest
中; 所有这些并行,并且知道t
不是默认的构造。
我最初尝试的是使用并行执行策略使用std :: transform
:
std::transform(std::execution::par_unseq,
source.begin(), source.end(),
dest.begin(),
[](const T& elem) { return op(elem); }
);
但是,当我第一次编译并运行此操作时,令我惊讶的是,我发现,尽管transform> transform
“ loops” for source.size()
times,dest
的内容保持不变。
我发现这是因为dest
必须在变换
之前具有相同的source
的大小。 但是,我无法将dest
调整到source
的大小,因为t
不默认构造,因为它没有默认的构造函数。我也希望不为其提供默认的构造函数(首先,在t
的逻辑中没有意义,但是您可以认为调用它会很昂贵)。
C ++ STL是否提供其他算法来实现我的想法?
足够的是算法,其中每个线程计算source
向量的部分,然后收集结果并将其连接到相同的dest
向量。
I have a const std::vector<T> source
of a big size, and a std::vector<T> dest
.
I want to apply a transformation to each element in source
and store it in dest
; all of this in parallel, and knowing that T
is not default constructible.
What I initially attempted was using std::transform
with a parallel execution policy:
std::transform(std::execution::par_unseq,
source.begin(), source.end(),
dest.begin(),
[](const T& elem) { return op(elem); }
);
However, when I first compiled and run this, to my surprise, I discovered that, although the transform
"loops" for source.size()
times, dest
's content remains unchanged.
I discovered that this is because dest
must have the same size of source
prior to the transform
.
However, I cannot do resize dest
to the size of source
, because T
is not default constructible as it does not have a default constructor. I also would prefer not to provide a default constructor for it (first of all, it does not make sense in T
's logic, but you can think that it would be expensive to call).
Does C++ STL offer any other algorithm for achieving what I have in mind?
What would suffice is an algorithm where each thread computes its own part of the source
vector, and then the results are collected and joined into the same dest
vector.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尝试使用
std :: vector&lt;&gt;
std ::可选&lt; t&gt;
:示例输出:
8 10 12 14 16 16 18 20 22 22
godbolt演示: https://godbolt.org/z/ecf955cneq
您的
dest
数组现在将每个元素包裹在std ::可选&lt;&gt;
容器中,但我相信它否则可以提供您指定的语义。Try using a
std::vector<>
ofstd::optional<T>
:Sample output:
8 10 12 14 16 18 20 22
Godbolt demo: https://godbolt.org/z/ecf95cneq
This is admittedly not that idiomatic, as your
dest
array now has every element wrapped up in anstd::optional<>
container, but I believe it otherwise offers the semantics you specify.还受到 @saxbophone的答案的启发,这是一个解决方案,该解决方案避免了
std ::可选
介绍的(次要)开销。它基于以下简单的,您的自己的容器:这需要一个
t
要构造并随后移动由std :: transform生成的每个元素,与
std ::可选
解决方案相同(我确实对此进行了测试)。请注意使用malloc
和免费
避免默认构建任何t
s。完整的代码为在这里,看起来像这样(它会产生与@sax相同的输出)
:要使用
SimpleVector
作为您喜欢的任何内容。如果需要,您随时可以添加访问器 /便利方法。Also inspired by @saxbophone's answer, here's a solution that avoids the (minor) overhead that
std::optional
introduces. It is based on the following simple, roll-your own container:This requires one
T
to be constructed and subsequently moved for each element generated bystd::transform
, which is the same as thestd::optional
solution (I did test this). Note the use ofmalloc
andfree
to avoid default-constructing anyT
s.The complete code is here and looks like this (it generates the same output as @sax):
Feel free to use
SimpleVector
for anything you like if you so choose. You can always add accessor / convenience methods to it if you need them.受@saxbophone答案的启发,您还可以使用指针的向量。
将代码模板归功于@saxbophone。
实时示例: https://godbolt.org/z/r73qr1ze3
Inspired by @saxbophone answer, you could also use a vector of pointers.
Credit for the code template to @saxbophone.
Live example: https://godbolt.org/z/r73qr1ze3