C++ 用C++;14个索引序列?

C++ 用C++;14个索引序列?,c++,templates,tuples,variadic-templates,c++14,C++,Templates,Tuples,Variadic Templates,C++14,在我的代码中,我有许多可变模板函数来处理std::tuple实例,类似于以下实例: // Convert JSON object to `std::tuple` template<int TI = 0, typename... TS> std::enable_if_t<TI == sizeof...(TS)> toTpl(const JVal&, std::tuple<TS...>&) { // Do nothing (end

在我的代码中,我有许多可变模板函数来处理
std::tuple
实例,类似于以下实例:

// Convert JSON object to `std::tuple`

template<int TI = 0, typename... TS> 
std::enable_if_t<TI == sizeof...(TS)> toTpl(const JVal&, std::tuple<TS...>&) 
{ 
    // Do nothing (end of the recursion)
}

template<int TI = 0, typename... TS> 
std::enable_if_t<TI < sizeof...(TS)> toTpl(const JVal& mV, std::tuple<TS...>& mX)
{
    std::get<TI>(mX) = mV[TI].as<std::tuple_element_t<TI, decltype(mX)>;    
    toTpl<TI + 1, TS...>(mV, mX);
}
//将JSON对象转换为'std::tuple'`
模板
std::如果toTpl(常量JVal&,std::tuple&)启用
{ 
//什么都不做(递归结束)
}
模板
std::如果toTpl(常量JVal&mV,std::tuple&mX)启用
{
std::get(mX)=mV[TI]。作为大小的…(TS)

我想知道新的C++14
std::integer_序列
std::index_序列
是否以及如何在这些情况下有所帮助

我希望使代码更可读(更易于维护)。提高编译时间也是一大优势


我尝试使用
std::index_sequence
但遇到了问题-我对它的用法感到困惑,尤其是当它作为函数中的参数传递时。

您可以执行以下操作:

template<typename Tuple, std::size_t... Is>
void toTpl(const JVal& mV, Tuple& t, std::index_sequence<Is...>)
{
    std::initializer_list<int> {
        (std::get<Is>(t) = mV[Is].as<std::tuple_element_t<Is, Tuple>>, void(), 0)...
    };
}

template<typename... TS>
void toTpl(const JVal& mV, std::tuple<TS...>& t)
{
    toTpl(mV, t, std::make_index_sequence<sizeof...(TS)>{});
}
模板
void toTpl(const JVal&mV、Tuple&t、std::index_序列)
{
std::初始值设定项列表{
(std::get(t)=mV[Is].as,void(),0)。。。
};
}
模板
void toTpl(const JVal&mV,std::tuple&t)
{
toTpl(mV,t,std::make_index_sequence{});
}
那怎么办

template <typename... T, std::size_t... I>
void toTpl_(const JVal& mV, std::tuple<T...>& mX, std::index_sequence<I...>)
{
    (void) std::initializer_list<int>{ (std::get<I>(mX) = mV[I].as<T>(), 0)... };
}

template <typename... TS>
void toTpl(const JVal& mV, std::tuple<TS...>& mX)
{
    toTpl_(mV, mX, std::index_sequence_for<TS...>() );
}

这显然会创建不必要的副本。

我会按值返回元组,以避免不必要的默认构造和讨厌的out参数:

template <typename... Ts, std::size_t... Is> 
auto toTpl(const JVal& mV, std::index_sequence<Is...>) 
{ 
    return std::tuple<Ts...>{ mV[Is].as<Ts>()... };
}

template<typename... Ts> 
auto toTpl(const JVal& mV)
{
    return toTpl<Ts...>(mV, std::index_sequence_for<Ts...>{});
}

// Usage:

auto t = toTpl<int, double, long>(mV);
这看起来很优雅,与
JVal::as

选项)的用法一致
模板
void toTpl(const JVal&mV,std::tuple&mX,std::index_序列)
{ 
使用Tuple=std::Tuple;
mX=std::forward_as_tuple(mV[Is].as()…);
}
模板
void toTpl(const JVal&mV,std::tuple&mX)
{
toTpl(mV,mX,std::make_index_sequence{});
}


选项2
模板
void toTpl(const JVal&mV,std::tuple&mX,std::index_序列)
{ 
使用Tuple=std::Tuple;
int-dummy[]={0,((void)(std::get(mX)=mV[Is].as()),0);
}
模板
void toTpl(const JVal&mV,std::tuple&mX)
{
toTpl(mV,mX,std::make_index_sequence{});
}


选项3
模板
void op(常量JVal和mV,std::tuple和mX)
{
使用Tuple=std::Tuple;
std::get(mX)=mV[N].as();
}
模板
void toTpl(const JVal&mV,std::tuple&mX,std::index_序列)
{ 
int-dummy[]={0,((void)op(mV,mX),0);
}
模板
void toTpl(const JVal&mV,std::tuple&mX)
{
toTpl(mV,mX,std::make_index_sequence{});
}

std::tuple\u element\u t
TS
的一个复杂拼写,当
是一个索引序列时。它不是不正确的,它是不必要的冗长。
std::tuple\u element\u t…
完全等同于
TS…
template <typename... Ts, std::size_t... Is> 
auto toTpl(const JVal& mV, std::index_sequence<Is...>) 
{ 
    return std::tuple<Ts...>{ mV[Is].as<Ts>()... };
}

template<typename... Ts> 
auto toTpl(const JVal& mV)
{
    return toTpl<Ts...>(mV, std::index_sequence_for<Ts...>{});
}

// Usage:

auto t = toTpl<int, double, long>(mV);
auto t = as_tuple<int, char, std::string>(some_json_value);
template <typename... TS, std::size_t... Is> 
void toTpl(const JVal& mV, std::tuple<TS...>& mX, std::index_sequence<Is...>) 
{ 
    using Tuple = std::tuple<TS...>;
    mX = std::forward_as_tuple(mV[Is].as<std::tuple_element_t<Is, Tuple>>()...);
}

template <typename... TS> 
void toTpl(const JVal& mV, std::tuple<TS...>& mX)
{
    toTpl(mV, mX, std::make_index_sequence<sizeof...(TS)>{});
}
template <typename... TS, std::size_t... Is> 
void toTpl(const JVal& mV, std::tuple<TS...>& mX, std::index_sequence<Is...>) 
{ 
    using Tuple = std::tuple<TS...>;
    int dummy[] = { 0, ((void)(std::get<Is>(mX) = mV[Is].as<std::tuple_element_t<Is, Tuple>>()), 0)... };
}

template <typename... TS> 
void toTpl(const JVal& mV, std::tuple<TS...>& mX)
{
    toTpl(mV, mX, std::make_index_sequence<sizeof...(TS)>{});
}
template <std::size_t N, typename... TS>
void op(const JVal& mV, std::tuple<TS...>& mX)
{
    using Tuple = std::tuple<TS...>;
    std::get<N>(mX) = mV[N].as<std::tuple_element_t<N, Tuple>>();
}

template <typename... TS, std::size_t... Is>
void toTpl(const JVal& mV, std::tuple<TS...>& mX, std::index_sequence<Is...>) 
{ 
    int dummy[] = { 0, ((void)op<Is>(mV, mX), 0)... };
}

template <typename... TS> 
void toTpl(const JVal& mV, std::tuple<TS...>& mX)
{
    toTpl(mV, mX, std::make_index_sequence<sizeof...(TS)>{});
}