问题描述
我希望插入一个转换函数(可能是std :: function)来修改被推到std :: vector上的对象。我希望该对象就位构造,并在不构造其他副本的情况下通过该函数。
假设我正在这样做:
std::vector<foo> foo_array;
foo_array.push_back(foo(foo_construct_arguments...));
现在我要这样做:
foo_array.push_back(convert(foo(foo_construct_arguments...)));
其中的“转换”是这样的:
std::function<foo &(foo&)> convert{ [&](foo &f)->foo& { return f; } }
很明显,该函数必须修改f才有用,但是在最简单的情况下,假设它只是返回对象。
我想以这样的语法结尾:
foo_array.emplace_back(convert(foo(foo_construct_arguments...)));
并构造一个foo实例,并通过convert函数对其进行修改,然后仅用一个结构将其放置在向量中。似乎应该有一些方法可以在适当的地方指定r值引用,以使这种情况发生,但是我对移动语义等并不十分了解,无法实现。我可以找到一路到达目的地的方法。
解决方法
这里需要的语法是:
std::function<foo&&(foo&&)> convert{[](foo&& f) -> foo&& { return std::move(f); } };
或者,完全通用的lambda fn
:
auto fn = [](auto&& f) -> decltype(auto) { return std::forward<decltype(f)>(f); };
std::function<foo&&(foo&&)> convert{fn};
如果此代码位于热路径上,则可能的话,您可能希望避免将lambda包装到std::function
中。
或者,emplace_back
返回对新元素的引用,然后您可以使用该引用就地修改元素:
std::vector<foo> foo_array;
std::function<void(foo&)> convert{...};
convert(foo_array.emplace_back(foo_construct_arguments...));