遍历嵌套的 C++11 元组
Traversing nested C++11 tuple
如果我有这个元组类型:
std::tuple<int, string, std::tuple<...>, int>
如何遍历它?我已经能够编写遍历平面元组的函数,但不能使用嵌套元组。
问题似乎在于处理嵌套元组中所有可以想象的类型的模板化函数或类型的任何实现,必须有这种情况:
template<typename T>
void somefunc(T t)
{
// Do something to t
}
这最终成为每种类型的重载解析的最佳选择,并且您无法递归遍历元组,因为您会丢失它是元组的信息。如果你尝试编写一个类或函数来试图确定它是否是一个元组,你仍然会遇到"false"的情况,它与上面有相同的问题,因为它最终匹配每种类型,元组专用版本被忽略。
有没有我不知道的方法可以检查某些东西是否是元组?
只需重载元组和非元组类型的someFunc()
函数:
template<typename... Ts>
void someFunc( const std::tuple<Ts...>& tuple )
{
/* traverse the elements of the tuple */
traverse_tuple( tuple );
}
template<typename T>
void someFunc( const T& value )
{
/* do something with the value */
}
其中traverse_tuple
与您实现的遍历非嵌套(平面)元组的函数相同。它为元组的每个成员调用someFunc()
。
对于元组遍历函数的实现,您可以查看此答案。
如果要检查类型T
是否为元组,这应该可以工作:
#include <type_traits>
#include <tuple>
template<typename> struct is_tuple : std::false_type {};
template<typename... Ts> struct is_tuple<std::tuple<Ts...>> : std::true_type {};
static_assert( is_tuple<std::tuple<int>>::value, "Oops" );
static_assert( !is_tuple<int>::value, "Oops" );
int main() {}
你可以专门化结构/类而不是专门的函数:根据您的情况调整以下内容(http://ideone.com/VgIJfj):
namespace details
{
template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type
for_each(const std::tuple<Tp...> &, FuncT)
{ }
template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
for_each(const std::tuple<Tp...>& t, FuncT f)
{
f(std::get<I>(t));
for_each<I + 1, FuncT, Tp...>(t, f);
}
template <typename T>
struct traverseType
{
void operator () (const T& t) const
{
std::cout << "it is a generic T:" << t << std::endl;
}
};
template <>
struct traverseType<int>
{
void operator () (int i) const
{
std::cout << "it is a int:" << i << std::endl;
}
};
// needed by the for_each.
struct traverseTypeCaller
{
template <typename T>
void operator () (const T& t) const
{
details::traverseType<T>()(t);
}
};
template <typename ...T>
struct traverseType<std::tuple<T...>>
{
void operator () (const std::tuple<T...>& t) const
{
std::cout << "it is a tuple:" << std::endl;
for_each(t, traverseTypeCaller());
}
};
}
template <typename T>
void traverseType(const T& t)
{
details::traverseTypeCaller()(t);
}
相关文章:
- 使用标准库在 c++11 中使用 std::tie 提取嵌套在元组中的元组
- 在 c++11 中迭代函子元组
- 如何将元组转换为C 11中的字节数组
- 使用GCC v4.8在Ubuntu 14.04上定义C 11中元组向量时的编译错误
- 使用 C++11 std::元组在大型项目中
- 如何使用递归类模板在 C++11 中写出元组的内容
- C++11 标记元组
- 如何在运行时检查 c++11 元组是否有可能的函数应用程序
- C++11绑定std::函数与存储元组和解包
- 如何使用 C++11 可变参数模板来定义由向量元组支持的元组向量
- 推导出 C++11 中元组元素的类型
- C++11 在运行时不使用 switch 为元组编制索引的方法
- 仅初始化c++11元组的第一个参数
- 在 C++11 中加入两个元组
- C++11-元组和移动语义
- 如何创建一个在 C++11 (STL) 中压缩两个元组的函数
- 从 C++11 中的容器元组中提取value_type元组
- 遍历嵌套的 C++11 元组
- 通过索引 C++11 访问元组元素
- C++11 元组性能