C++ 通过索引在运行时访问std::tuple元素的最佳方法
我在中设计了一个函数C++ 通过索引在运行时访问std::tuple元素的最佳方法,c++,templates,c++11,template-meta-programming,stdtuple,C++,Templates,C++11,Template Meta Programming,Stdtuple,我在中设计了一个函数,用于通过运行时指定的索引访问std::tuple元素 template<std::size_t _Index = 0, typename _Tuple, typename _Function> inline typename std::enable_if<_Index == std::tuple_size<_Tuple>::value, void>::type for_each(_Tuple &, _Function) {} t
,用于通过运行时指定的索引访问std::tuple元素
template<std::size_t _Index = 0, typename _Tuple, typename _Function>
inline typename std::enable_if<_Index == std::tuple_size<_Tuple>::value, void>::type
for_each(_Tuple &, _Function)
{}
template<std::size_t _Index = 0, typename _Tuple, typename _Function>
inline typename std::enable_if < _Index < std::tuple_size<_Tuple>::value, void>::type
for_each(_Tuple &t, _Function f)
{
f(std::get<_Index>(t));
for_each<_Index + 1, _Tuple, _Function>(t, f);
}
namespace detail { namespace at {
template < typename _Function >
struct helper
{
inline helper(size_t index_, _Function f_) : index(index_), f(f_), count(0) {}
template < typename _Arg >
void operator()(_Arg &arg_) const
{
if(index == count++)
f(arg_);
}
const size_t index;
mutable size_t count;
_Function f;
};
}} // end of namespace detail
template < typename _Tuple, typename _Function >
void at(_Tuple &t, size_t index_, _Function f)
{
if(std::tuple_size<_Tuple> ::value <= index_)
throw std::out_of_range("");
for_each(t, detail::at::helper<_Function>(index_, f));
}
模板
内联类型名称std::enable_if::type
对于每个(_元组&,_函数)
{}
模板
内联类型名称std::启用(如果<_索引::类型
对于每个(_元组&t,_函数f)
{
f(std::get(t));
对于_(t,f);
}
命名空间详细信息{位于的命名空间{
模板
结构辅助程序
{
内联帮助器(大小、索引、函数):索引(索引)、f(f)、计数(0){
模板
void运算符()
{
如果(索引==count++)
f(arg_);
}
常数大小指数;
可变大小计数;
_函数f;
};
}}//名称空间详细信息的结尾
模板
空值(_元组&t,大小\u t索引,_函数f)
{
如果(std::tuple_size::value假设您传递类似于通用lambda的内容,即带有重载函数调用运算符的函数对象:
#include <iostream>
struct Func
{
template<class T>
void operator()(T p)
{
std::cout << __PRETTY_FUNCTION__ << " : " << p << "\n";
}
};
#包括
结构函数
{
模板
void运算符()(tp)
{
std::tuple
类型是否统一?@Yakk通常情况下,它们不统一。我不确定优化器是否能做到这一点,但也许你可以通过元编程生成一系列的if-else if-else if
,用开关/查找表代替。构建n个元素数组是O(n)@Yakk现在是静态的;)谢谢。我不能用msvs2013编译你们的代码,但这个想法对我来说很清楚me@sliser嗯,\uu PRETTY\u FUNCTION\uuu
宏是非标准的,但其余的不应该太花哨。..msvs2013在使用和constepr
关键字时有问题
#include <tuple>
template<int... Is> struct seq {};
template<int N, int... Is> struct gen_seq : gen_seq<N-1, N-1, Is...> {};
template<int... Is> struct gen_seq<0, Is...> : seq<Is...> {};
template<int N, class T, class F>
void apply_one(T& p, F func)
{
func( std::get<N>(p) );
}
template<class T, class F, int... Is>
void apply(T& p, int index, F func, seq<Is...>)
{
using FT = void(T&, F);
static constexpr FT* arr[] = { &apply_one<Is, T, F>... };
arr[index](p, func);
}
template<class T, class F>
void apply(T& p, int index, F func)
{
apply(p, index, func, gen_seq<std::tuple_size<T>::value>{});
}
int main()
{
std::tuple<int, double, char, double> t{1, 2.3, 4, 5.6};
for(int i = 0; i < 4; ++i) apply(t, i, Func{});
}
static FT* arr[] = { [](T& p, F func){ func(std::get<Is>(p)); }... };