【问题标题】:How to forward the values of a tuple? std::get( move(tuple) ) vs. forward( std::get(tuple) )如何转发元组的值? std::get( move(tuple) ) vs. forward( std::get(tuple) )
【发布时间】:2020-07-07 06:45:45
【问题描述】:

假设您编写类似“初始化程序”类的东西,它存储一组值(包括引用)。然后使用这些值初始化给定类型(例如通过my_initializer.initialize<Foo>():

template<typename... Values>
struct Initializer{
    std::tuple<Values...> values;

    template<typename TypeToInitialize, std::size_t... Is>
    TypeToInitialize initialize_implementation( std::index_sequence<Is...> ){
        return { std::get<Is>( this->values )... };
    }

    template<typename TypeToInitialize>
    TypeToInitialize initialize(){
        return initialize_implementation( std::make_index_sequence<sizeof...(Values)>() );
    }
};

相当简单的沙发。但是,现在我想为 rvalue 对象提供 initialize() 的重载,只要调用它的对象是 rvalue 并且调用 initialize&lt;...&gt;()是对象被销毁之前的最后一个动作。

如何转发元组的值?我应该选择哪个选项?

template<typename TypeToInitialize, std::size_t... Is>
TypeToInitialize initialize_move_implementation( std::index_sequence<Is...> )
{
    // OPTION 1
    return { std::forward<Values>( std::get<Is>( this->values ) )... };

    // OPTION 2
    return { std::get<Is>( std::move( this->values ) )... };
}

template<typename TypeToInitialize>
TypeToInitialize initialize() && {
    return initialize_move_implementation<TypeToInitialize>( std::make_index_sequence<sizeof...(Values)>() );
}

【问题讨论】:

标签: c++ move-semantics perfect-forwarding stdtuple


【解决方案1】:
template<typename TypeToInitialize>
TypeToInitialize initialize() && {
    return std::make_from_tuple<TypeToInitialize>(this->values);
}

在内部,它执行以下操作:

return T(std::get<I>(std::forward<Tuple>(t))...);

I 是一个索引序列,就像您的原始示例一样。

【讨论】:

  • 不应该this-&gt;values仍然被显式移动吗?
  • 是的,绝对;)
【解决方案2】:

如果存储的值是TT&amp;&amp; 类型(假设T 是一个对象类型),这两个选项都产生T&amp;&amp;;如果存储的值是T&amp; 类型,则两个选项都会产生T&amp;,所以我认为这两个选项之间没有区别。我个人喜欢选项 2,因为 forward 通常与通用引用一起使用,以将函数的参数转发到另一个函数,而在这里您将转发存储在类成员中的值,这可能有点令人困惑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-11
    • 2019-06-15
    • 1970-01-01
    • 2022-01-11
    • 2016-07-08
    • 2016-06-15
    • 1970-01-01
    相关资源
    最近更新 更多