如何完美转发多个结构体成员

Tom*_*Tom 5 c++ stl c++14 c++17

我希望弄清楚将多个成员从同一转发引用转发到结构的正确方法。

例子

下面是从转发引用参数将两个字段 (one_fieldanother_field) 转发到类构造函数 ( )的示例。这就是我之前认为我们应该这样做的:widgetinfo

template<typename Bundle>
auto make_widget(Bundle&& info) {
    return widget(
        std::forward<Bundle>(info).one_field,
        std::forward<Bundle>(info).another_field);
}
Run Code Online (Sandbox Code Playgroud)

然而,根据对reddit 的 C++ 线程的讨论,我担心这不是最佳实践,或者更糟糕的是这不安全。根据这个线程,使用这个习惯用法来转发单个forward成员字段显然是可以的,但是这个声明让我担心通过调用一次以上来转发多个字段是不安全的。

FWD(t).field:转发t.field,并使t及其所有成员无效(我的重点)

让我担心的是,如果的所有字段都info因首字母std::forward<Bundle>(info)!而无效,那么我的示例是不正确的。

我们应该如何以理论上和实践上安全的方式传递多个结构体字段?我非常希望不需要编写一个变体,std::forward根据父结构类型的语义来移动其参数。

参考

关于单一领域成员的 Reddit 讨论:https://www.reddit.com/r/cpp/comments/q4mchr/overview_of_ Different_ways_of_passing_struct/

对多个转发的评论:https://www.reddit.com/r/cpp/comments/q4mchr/comment/hfzsidd/ 发现这篇文章表明这​​在“实践中”是可以的,但考虑到 C++ 错误的微妙性,我很热衷要知道这“理论上”也是可以的!我希望,由于在幕后std::forwardstatic_cast右值类型,因此其他字段不会像实际调用移动构造函数时那样发生失效。

类似的SO问题(对于单个成员字段):如何完美转发结构成员?

谢谢大家。

app*_*ple 1

您已经执行了正确的操作(即将成员作为 Bundle 转发)并且访问字段并不像使父对象无效。

template<typename Bundle>
auto make_widget(Bundle&& info) {
    return widget(
        std::forward<Bundle>(info).one_field,
        std::forward<Bundle>(info).another_field
    );
}
Run Code Online (Sandbox Code Playgroud)

如果你愿意,你也可以使用类似std::forward_likec++23 的东西

template<typename Bundle>
auto make_widget(Bundle&& info) {
    return widget(
       std::forward_like<Bundle>(info.one_field),
       std::forward_like<Bundle>(info.another_field)
    );
}
Run Code Online (Sandbox Code Playgroud)