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++14std::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)>{});
}