如何转发元组的值?std::get(move(tuple))与forward(std::get(tuple))



假设您编写了类似于"初始值设定项"类的东西,该类存储一组值(包括引用(。然后使用这些值初始化给定类型(例如通过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)>() );
}
};

相当简单的沙发。但是,现在我想为右值对象提供一个initialize()的重载,只要调用它的对象是右值,并且对initialize<...>()的调用是对象被销毁之前的最后一个操作,就会调用它。

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

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)>() );
}
template<typename TypeToInitialize>
TypeToInitialize initialize() && {
return std::make_from_tuple<TypeToInitialize>(this->values);
}

在内部,它做的事情类似于:

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

其中I是一个索引序列,类似于原始示例中的索引序列。

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

最新更新