递归可变参数模板在 C++11 中由 std::tuple_size 终止
Recursive variadic template terminated by std::tuple_size in C++11
我在实现递归模板(模板结构中的函数)时遇到问题,它将由 std::tuple_size 终止。
这是代码片段(我简化了代码,以强调问题):
template<int index, typename ...T_arguments>
struct Helper
{
static void func (size_t& return_size,
const std::tuple<T_arguments...>& arguments)
{
const auto& argument (std::get<index> (arguments));
return_size += ::value_size (argument);
::Helper<index + 1, T_arguments...>::func (return_size, arguments);
}
// ...
template<typename... T_arguments>
struct Helper<std::tuple_size<T_arguments...>::value, T_arguments...>
{
static void func (size_t& return_size,
const std::tuple<T_arguments...>& arguments)
{
const auto& argument (std::get<std::tuple_size<T_arguments...>::value> (arguments));
return_size += ::value_size (argument);
}
初始模板调用如下所示:
Helper<0, T_arguments...>::func (return_size, arguments);
GCC 失败并显示错误:
错误:模板参数"std::tuple_size::值" 涉及模板参数 结构 帮助程序::值, T_arguments...>
std::tuple_size
声称在编译时是已知的,那么为什么我不能使用它模板专用化呢?
实际上,
您正在做的事情是第 §14.5.4/9 节禁止的,该节规定:
部分专用非类型参数表达式不得涉及部分专用化的模板参数,除非参数表达式是简单标识符。
以下可能会有所帮助:
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type
total_value_size(size_t& return_size, const std::tuple<Tp...>& t)
{ }
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
total_value_size(size_t& return_size, const std::tuple<Tp...>& t)
{
const auto& argument (std::get<I> (t));
return_size += ::value_size(argument);
total_value_size<I + 1, Tp...>(return_size, t);
}
使用 index_sequence 和基于范围。
#include <cstdlib>
#include <cstddef>
#include <tuple>
namespace mpl
{
template< std::size_t ... I>
struct index_sequence
{
};
template< std::size_t s, typename I1, typename I2>
struct concate;
template< std::size_t s, std::size_t ...I, std::size_t ...J>
struct concate<s, index_sequence<I...>, index_sequence<J...> >
{
typedef index_sequence<I... ,( J + s)... > type;
};
template< std::size_t N>
struct make_index_sequence
{
typedef typename concate< N/2,
typename make_index_sequence< N/2>::type,
typename make_index_sequence< N - N/2>::type
>::type type;
};
template<>struct make_index_sequence<0>
{
typedef index_sequence<> type;
};
template<> struct make_index_sequence<1>
{
typedef index_sequence<0> type;
};
template< typename ...T>
struct index_sequence_for
{
typedef typename make_index_sequence< sizeof...(T) > ::type type;
};
} // mpl
template< typename T >
std::size_t value_size( T ){ return sizeof(T); }// only for illustration
template< typename ...Tp, std::size_t ...i>
std::size_t total_value_size_impl( const std::tuple<Tp...> & t, mpl::index_sequence<i...> )
{
std::size_t result=0;
for(auto x: { value_size( std::get<i>(t) ) ... } )
{
result += x;
}
return result;
}
template< typename ...Tp>
std::size_t total_value_size( const std::tuple<Tp...> & t)
{
typedef typename mpl::index_sequence_for<Tp...> :: type indexes;
return total_value_size_impl( t, indexes{} );
}
#include <cstdio>
int main()
{
typedef std::tuple<int, char, double> types;
std::size_t result = total_value_size(types{});
printf("%dn", result);
}
相关文章:
- 在 std::tuple 上使用 std::variant 的问题
- 在构造函数中使用可变参数初始化 std::tuple
- 转发复制的 std::tuple
- 我可以将新的 std::tuple 放入内存映射区域,并在以后读回吗?
- std::tuple 可以根据其值在编译时/运行时排序吗?
- 返回 std::tuple 中的引用和值
- 带有引用的std::tuple在clang中编译失败,但在gcc中编译失败
- 尝试实现std::tie和std::tuple的小版本
- std::tuple默认构造函数,带有move可构造元素
- 来自带有 std::tuple 的地图
- 如何从 std::async 任务返回 std::tuple
- 为什么 std::when_any 使用 std::tuple 而不是 std::vector 作为其结果类型?
- 为什么 std::integral_constant 在爆炸 std::tuple 时是必需的?
- 如何在std :: tuple中的每个元素上应用constexpr函数
- 如果创建支持返回可变参数类型列表的通用模板 API,我应该使用 std::tuple 还是其他东西?
- 类型安全 - all_of/ any_of/ none_of for std::tuple
- 将__m128i值转换为 std::tuple
- 使结构的行为类似于 std::tuple
- std::tuple faster than std::array?
- C++ 在标准::unordered_map中设置 std::tuple 值