c++11:从模板函数构建 std::tuple
c++11: building a std::tuple from a template function
我有以下功能:
template<class T>
T Check(int index);
如何编写函数 CheckTuple
,给定元组类型,通过调用 Check
?[=16 来填充元组=]
例如:
CheckTuple< std::tuple<int, float, std::string> >()
将return以下元组:
std::make_tuple( Check<int>(1), Check<float>(2), Check<std::string>(3) )
我看到的其他问题涉及解包一个给定的元组,而不是用这种方式构建一个元组。
这是我的工作测试实现。 (也许有人知道如何在简洁性方面改进它。我能以某种方式摆脱 TupleInfo 吗?)
#include <typeinfo>
#include <tuple>
#include <iostream>
template<class T>
T Check(int i) {
std::cout << "getting a " << typeid(T).name() << " at position " << i << std::endl;
return T();
}
template<typename Signature>
struct TupleInfo;
template<class T, class... Args>
struct TupleInfo< std::tuple<T, Args...> > {
using Head = T;
using Tail = std::tuple<Args...>;
};
template<int N, class Tuple>
struct TupleChecker {
static Tuple CheckTuple() {
auto t = std::make_tuple(Check<typename TupleInfo<Tuple>::Head>(N));
return std::tuple_cat(t, TupleChecker<N+1, typename TupleInfo<Tuple>::Tail >::CheckTuple());
}
};
template<int N>
struct TupleChecker<N, std::tuple<> > {
static std::tuple<> CheckTuple() {
return std::tuple<>();
}
};
template<class Tuple>
Tuple CheckTuple() {
return TupleChecker<1, Tuple>::CheckTuple();
}
int main() {
std::tuple<> t0 = CheckTuple<std::tuple<> >();
std::tuple<int> t1 = CheckTuple<std::tuple<int> >();
std::tuple<int, float, std::string> t2 = CheckTuple<std::tuple<int, float, std::string> >();
return 0;
}
使用 C++14 integer_sequence
. If you don't have that available, here's a C++11 implementation written by Jonathan Wakely.
实现您正在寻找的东西变得非常简单
template<typename Tuple, int... I>
Tuple CallCheck(std::integer_sequence<int, I...>)
{
return std::make_tuple(Check<typename std::tuple_element<I, Tuple>::type>(I)...);
}
template<typename Tuple>
Tuple CheckTuple()
{
return CallCheck<Tuple>(std::make_integer_sequence<int, std::tuple_size<Tuple>::value>());
}
// Use it as
auto tup = CheckTuple<std::tuple<int, float, std::string>>();
我有以下功能:
template<class T>
T Check(int index);
如何编写函数 CheckTuple
,给定元组类型,通过调用 Check
?[=16 来填充元组=]
例如:
CheckTuple< std::tuple<int, float, std::string> >()
将return以下元组:
std::make_tuple( Check<int>(1), Check<float>(2), Check<std::string>(3) )
我看到的其他问题涉及解包一个给定的元组,而不是用这种方式构建一个元组。
这是我的工作测试实现。 (也许有人知道如何在简洁性方面改进它。我能以某种方式摆脱 TupleInfo 吗?)
#include <typeinfo>
#include <tuple>
#include <iostream>
template<class T>
T Check(int i) {
std::cout << "getting a " << typeid(T).name() << " at position " << i << std::endl;
return T();
}
template<typename Signature>
struct TupleInfo;
template<class T, class... Args>
struct TupleInfo< std::tuple<T, Args...> > {
using Head = T;
using Tail = std::tuple<Args...>;
};
template<int N, class Tuple>
struct TupleChecker {
static Tuple CheckTuple() {
auto t = std::make_tuple(Check<typename TupleInfo<Tuple>::Head>(N));
return std::tuple_cat(t, TupleChecker<N+1, typename TupleInfo<Tuple>::Tail >::CheckTuple());
}
};
template<int N>
struct TupleChecker<N, std::tuple<> > {
static std::tuple<> CheckTuple() {
return std::tuple<>();
}
};
template<class Tuple>
Tuple CheckTuple() {
return TupleChecker<1, Tuple>::CheckTuple();
}
int main() {
std::tuple<> t0 = CheckTuple<std::tuple<> >();
std::tuple<int> t1 = CheckTuple<std::tuple<int> >();
std::tuple<int, float, std::string> t2 = CheckTuple<std::tuple<int, float, std::string> >();
return 0;
}
使用 C++14 integer_sequence
. If you don't have that available, here's a C++11 implementation written by Jonathan Wakely.
template<typename Tuple, int... I>
Tuple CallCheck(std::integer_sequence<int, I...>)
{
return std::make_tuple(Check<typename std::tuple_element<I, Tuple>::type>(I)...);
}
template<typename Tuple>
Tuple CheckTuple()
{
return CallCheck<Tuple>(std::make_integer_sequence<int, std::tuple_size<Tuple>::value>());
}
// Use it as
auto tup = CheckTuple<std::tuple<int, float, std::string>>();