如何使用递归类模板在 C++11 中写出元组的内容
How to write out contents of a tuple in C++11 using recursive class templates?
我尝试了以下递归来写出tuple
的元素,但是在编译时计算tuple
大小的行中遇到了麻烦(下面注释掉了):
#include <tuple>
#include <string>
#include <iostream>
template<typename Tuple, std::size_t element = 0>
struct write_tuple
{
static void execute(Tuple const & t)
{
std::cout << std::get<element>(t) << std::endl;
write_tuple<Tuple, element + 1>::execute(t);
}
};
template<typename Tuple>
struct write_tuple<Tuple, 4> // This works fine
//struct write_tuple<Tuple, std::tuple_size<typename Tuple>::value > // std::tuple_size should give me the size of the tuple at compile-time
{
static void execute(Tuple const & t) {};
};
template<typename Tuple>
void write(Tuple const & t)
{
write_tuple<Tuple>::execute(t);
}
using namespace std;
int main(int argc, const char *argv[])
{
tuple<string, int, double, string> myTuple = std::make_tuple("test", 0, 2.1, "finished");
write(myTuple);
return 0;
}
该行:
struct write_tuple<Tuple, 4>
可以很好地终止大小为 4 的tuple
的递归调用,但是当我在编译时使用std::tuple_size<typename Tuple>::value
获取tuple
大小时,出现以下错误:
main.cpp:17:57: error: template argument 1 is invalid
struct write_tuple<Tuple, std::tuple_size<typename Tuple>::value > // std::tuple_size should give me the size of the tuple at compile-time
^
main.cpp:17:66: error: template argument 2 is invalid
struct write_tuple<Tuple, std::tuple_size<typename Tuple>::value > // std::tuple_size should give me the size of the tuple at compile-time
我正在使用 gcc 4.8.2。
编辑:
从std::tuple_size<typename Tuple>::value
结果中删除typename
,并显示以下错误:
g++ -std=c++11 main.cpp -o main 2>&1 | tee log
main.cpp:17:8: error: template argument ‘std::tuple_size<_Tp>::value’ involves template parameter(s)
struct write_tuple<Tuple, std::tuple_size<Tuple>::value> // std::tuple_size should give me the size of the tuple at compile-time
对于您的代码,您可以反转递归,例如:
template<typename Tuple, std::size_t remaining>
struct write_tuple
{
static void execute(Tuple const & t)
{
std::cout << std::get<std::tuple_size<Tuple>::value - remaining>(t) << std::endl;
write_tuple<Tuple, remaining - 1>::execute(t);
}
};
template<typename Tuple>
struct write_tuple<Tuple, 0>
{
static void execute(Tuple const & t) {};
};
template<typename Tuple>
void write(Tuple const & t)
{
write_tuple<Tuple, std::tuple_size<Tuple>::value>::execute(t);
}
另一种方法:
#include <tuple>
#include <iostream>
#include <cstdint>
#if 1 // Not in C++11
template <std::size_t ...> struct index_sequence {};
template <std::size_t N, std::size_t ...Is>
struct make_index_sequence : make_index_sequence<N - 1, N - 1, Is...> {};
template <std::size_t ... Is>
struct make_index_sequence<0, Is...> : index_sequence<Is...> {};
#endif // make_index_sequence
template<typename Tuple>
struct write_tuple
{
static void execute(Tuple const & t)
{
execute(t, make_index_sequence<std::tuple_size<Tuple>::value>());
}
private:
template<std::size_t ... Is>
static void execute(Tuple const & t, index_sequence<Is...>)
{
const int dummy[] = {0, (write_element(std::get<Is>(t)), 0)...};
static_cast<void>(dummy); // silent warning for unused variable.
}
template <typename T>
static void write_element(T const &elem)
{
std::cout << elem << std::endl;
}
};
这是该语言的一个怪癖:非类型参数值不能依赖于专用化中的类型参数值。 标准化委员会可能是有原因的。 这可能是一个好主意。
有几种方法可以解决您的问题,最简单的 beimg 递归到0
并在返回递归的途中打印。 对代码进行最少更改的一种方法是将, typename=void>
参数添加到class template
,并在专用化中添加大小,然后, size, typename std::enable_if<size==std::tuple_size<Tuple>::value>::type>
添加到专用化末尾。 这使得测试成为类型参数,专门用于void
(始终存在),但仅在 SFINAE 成功且大小与元组大小匹配时才有效。
相关文章:
- 使用标准库在 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 元组性能