【发布时间】:2021-06-04 16:07:23
【问题描述】:
我正在尝试创建一个基本上接受函数指针及其所有参数的函数,并将函数和这些参数存储在 std::function 和 std::tuple 中以供以后使用。我当然看到了使用可变参数的函数的典型模式,将它们完美地转发到某个地方进行存储。我在How to store variadic template arguments? 中看到了这个解决方案,它非常适合我的情况,直到我意识到它似乎只接受包装在std::ref() 或std::move()d 中的函数参数,我根本无法存储变量值。
在寻找另一种允许我按值和引用存储参数的解决方案时,我遇到了c++ store function and parameter list for later use,我打算重新利用它。但同时,我真的很想了解为什么第一个解决方案不允许我通过值传递任何东西:
template <typename... Ts>
class TupleCarrier {
public:
TupleCarrier(Ts&&... args): args_(std::make_tuple(std::forward<Ts>(args)...)) {}
std::tuple<Ts...> args_;
};
template <typename... Ts>
void CreateCarrier(Ts&&... args) {
TupleCarrier<Ts...> carrier(std::forward<Ts>(args)...);
}
int main() {
int test = 4;
CreateCarrier(std::ref(test), /*std::ref(*/test/*)*/); // fails to compile
return 0;
}
是否像CreateCarrier 将参数作为右值引用一样简单,std::forward 要么将它们作为右值或左值引用转发,但这里根本没有办法传递常规的旧左值?我希望左值至少会被隐式视为左值引用,如果您打算按值传递,这当然可能会出现问题,但至少它会编译......
无论如何,我认为我对上述内容的微妙理解不足以自己提出正确的答案,所以这里的某种解释真的会帮助我理解一些更高级的 C++ :)
【问题讨论】:
-
为什么不采用 0 arg 函数,让调用者将其捆绑在 lambda 中。我的意思是分开争论很可爱,但通常是浪费工作。
-
std容器不能保存引用&。为了让std容器保存引用,您必须将它们包装在std::reference_wrapper中。 -
我想我在下面回答你的问题非常正确和简洁......小心给我解决方案,因为我解决了它? :-P
-
抱歉耽搁了
标签: c++ templates rvalue-reference lvalue