为什么编译器会尝试实例化错误的 STL 模板? (BinaryOperation 而不是 UnaryOperation)
Why does the compiler try to instantiate the wrong STL template? (BinaryOperation instead of UnaryOperation)
我想将 std::transform
与并行执行策略一起使用。 documentation 告诉使用模板 (2):
template< class ExecutionPolicy,
class ForwardIt1,
class ForwardIt2,
class UnaryOperation >
ForwardIt2 transform( ExecutionPolicy&& policy,
ForwardIt1 first1,
ForwardIt1 last1,
ForwardIt2 d_first,
UnaryOperation unary_op );
我的代码如下,和模板好像很吻合:
const std::vector<SimulatedBody>& bodies = m_data.back().m_bodies;
std::vector<SimulatedBody> updated_bodies;
std::transform(std::execution::par,
bodies.begin(),
bodies.end(),
std::back_inserter(updated_bodies),
[&](const SimulatedBody& body) {
return body.updated(*quadtree, m_dt, m_force_algorithm_fn);
});
body.updated
的return类型是新的SimulatedBody
:
SimulatedBody SimulatedBody::updated(
const bh::Node& quadtree, float dt,
const std::function<Vector2d(const Node&, const Body&)>&
force_algorithm_fn = bh::compute_approximate_net_force_on_body) const
但是,当我编译时,它引发了以下错误:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/pstl/glue_algorithm_impl.h:325:44: error: argument may not have 'void' type
[__op](_InputType __x, _OutputType __y) mutable { __y = __op(__x); },
^
/home/steddy/CLionProjects/barnes-hut/src/simulation/simple_simulator.cpp:35:8: note: in instantiation of function template specialization 'std::transform<const __pstl::execution::parallel_policy &, __gnu_cxx::__normal_iterator<const bh::SimulatedBody *, std::vector<bh::SimulatedBody>>, std::back_insert_iterator<std::vector<bh::SimulatedBody>>, (lambda at /home/steddy/CLionProjects/barnes-hut/src/simulation/simple_simulator.cpp:37:18)>' requested here
std::transform(std::execution::par, bodies.begin(), bodies.end(),
^
从错误来看,似乎是编译器试图使用错误的模板;特别是带有 BinaryOperation 的一个。
我是不是漏掉了什么?
我使用的是 gcc 版本 12.1.1 20220507 (Red Hat 12.1.1-1)。
My code [...] seems to match the template:
它没有:
template< class ExecutionPolicy,
class ForwardIt1,
class ForwardIt2,
class UnaryOperation >
ForwardIt2 transform( ExecutionPolicy&& policy,
ForwardIt1 first1,
ForwardIt1 last1,
ForwardIt2 d_first, // < here
UnaryOperation unary_op );
在 Parameters 部分,您链接的文档指定了目标范围的开始,参数 d_first
,应该是一个前向迭代器:
Type requirements
- [...]
ForwardIt1
, ForwardIt2
, ForwardIt3
must meet the requirements of LegacyForwardIterator.
您正在向它传递一个输出迭代器,即:
std::back_inserter(updated_bodies)
如果 SimulatedBody
是默认可构造的,您可以将 updated_bodies
的大小调整为 bodies
的大小并传递 updated_bodies.begin()
(这是一个 random-access 迭代器,因此也是一个前向迭代器)到 std::transform
:
const std::vector<SimulatedBody>& bodies = m_data.back().m_bodies;
std::vector<SimulatedBody> updated_bodies;
updated_bodies.resize(bodies.size()); // Resize output vector
std::transform(std::execution::par,
bodies.begin(),
bodies.end(),
updated_bodies.begin(), // Pass iterator to first element
[&](const SimulatedBody& body) {
return body.updated(*quadtree, m_dt, m_force_algorithm_fn);
});
我想将 std::transform
与并行执行策略一起使用。 documentation 告诉使用模板 (2):
template< class ExecutionPolicy,
class ForwardIt1,
class ForwardIt2,
class UnaryOperation >
ForwardIt2 transform( ExecutionPolicy&& policy,
ForwardIt1 first1,
ForwardIt1 last1,
ForwardIt2 d_first,
UnaryOperation unary_op );
我的代码如下,和模板好像很吻合:
const std::vector<SimulatedBody>& bodies = m_data.back().m_bodies;
std::vector<SimulatedBody> updated_bodies;
std::transform(std::execution::par,
bodies.begin(),
bodies.end(),
std::back_inserter(updated_bodies),
[&](const SimulatedBody& body) {
return body.updated(*quadtree, m_dt, m_force_algorithm_fn);
});
body.updated
的return类型是新的SimulatedBody
:
SimulatedBody SimulatedBody::updated(
const bh::Node& quadtree, float dt,
const std::function<Vector2d(const Node&, const Body&)>&
force_algorithm_fn = bh::compute_approximate_net_force_on_body) const
但是,当我编译时,它引发了以下错误:
/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/pstl/glue_algorithm_impl.h:325:44: error: argument may not have 'void' type
[__op](_InputType __x, _OutputType __y) mutable { __y = __op(__x); },
^
/home/steddy/CLionProjects/barnes-hut/src/simulation/simple_simulator.cpp:35:8: note: in instantiation of function template specialization 'std::transform<const __pstl::execution::parallel_policy &, __gnu_cxx::__normal_iterator<const bh::SimulatedBody *, std::vector<bh::SimulatedBody>>, std::back_insert_iterator<std::vector<bh::SimulatedBody>>, (lambda at /home/steddy/CLionProjects/barnes-hut/src/simulation/simple_simulator.cpp:37:18)>' requested here
std::transform(std::execution::par, bodies.begin(), bodies.end(),
^
从错误来看,似乎是编译器试图使用错误的模板;特别是带有 BinaryOperation 的一个。
我是不是漏掉了什么?
我使用的是 gcc 版本 12.1.1 20220507 (Red Hat 12.1.1-1)。
My code [...] seems to match the template:
它没有:
template< class ExecutionPolicy,
class ForwardIt1,
class ForwardIt2,
class UnaryOperation >
ForwardIt2 transform( ExecutionPolicy&& policy,
ForwardIt1 first1,
ForwardIt1 last1,
ForwardIt2 d_first, // < here
UnaryOperation unary_op );
在 Parameters 部分,您链接的文档指定了目标范围的开始,参数 d_first
,应该是一个前向迭代器:
Type requirements
- [...]
ForwardIt1
,ForwardIt2
,ForwardIt3
must meet the requirements of LegacyForwardIterator.
您正在向它传递一个输出迭代器,即:
std::back_inserter(updated_bodies)
如果 SimulatedBody
是默认可构造的,您可以将 updated_bodies
的大小调整为 bodies
的大小并传递 updated_bodies.begin()
(这是一个 random-access 迭代器,因此也是一个前向迭代器)到 std::transform
:
const std::vector<SimulatedBody>& bodies = m_data.back().m_bodies;
std::vector<SimulatedBody> updated_bodies;
updated_bodies.resize(bodies.size()); // Resize output vector
std::transform(std::execution::par,
bodies.begin(),
bodies.end(),
updated_bodies.begin(), // Pass iterator to first element
[&](const SimulatedBody& body) {
return body.updated(*quadtree, m_dt, m_force_algorithm_fn);
});