繁体   English   中英

C++ 前向可变参数模板化 arguments 到元组

[英]C++ Forward variadic templated arguments to tuple

I'm trying to create a function that basically takes in a function pointer as well as all of its arguments, and store the function and these arguments in a std::function and std::tuple for later use. 我当然看到了 function 的典型模式,它消耗可变参数 arguments,完美地将它们转发到某个地方进行存储。 我在如何存储可变参数模板 arguments? ,这对我的情况很有效,直到我意识到它似乎只接受包装在std::ref()std::move() d 中的 function 参数,我根本无法存储变量值.

在寻找另一种允许我按值和引用存储参数的解决方案时,我遇到了c++ 存储 function 和参数列表供以后使用,我打算重新利用它们。 但与此同时,我真的很想了解为什么第一个解决方案不允许我按值传递任何东西:

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将 arguments 作为右值引用一样简单,而 std::forward 将它们作为右值或左值引用转发,但根本没有办法在这里传递常规的旧左值? 我希望左值至少会被隐式视为左值引用,如果您打算按值传递,这当然可能会出现问题,但至少它会编译......

无论如何,我认为我对上述细节的理解不足以自己提出正确的答案,所以这里的某种解释真的会帮助我理解一些更高级的 C++ :)

问题在于定义 std::make_tuple() 的方式:它 std::decay<> 是它的参数类型。

检查https://en.cppreference.com/w/cpp/utility/tuple/make_tuple “可能的实现”部分以查看详细信息。

所以,发生的事情是, _args 成员最终成为:

std::tuple<std::reference_wrapper<int>,int &>

因为那里没有添加衰变。 但是 make_tuple() 的结果是 std::tuple< int&, int > - int 的标识在此过程中丢失 - 您将引用初始化器的 value 参数 - 这将是一个挂起的引用。 因此,您的第一个元组 position 中的 int& 不能通过按值传递的 int 参数初始化。

无论如何,解决方案也是以这种方式衰减 args_ 声明:

std::tuple< std::decay_t< Ts > ...> args_;

然后事情编译得很好,因为你已经将接收器 (args_) 与 make_tuple() 的结果相匹配,它在内部衰减了它的 arguments。

然后 args_ 的类型最终是:

std::tuple<std::reference_wrapper<int>,int>

一切都是共病的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM