如何使我的 sizeof sum 结构与空参数包一起工作

How do I make my sizeof sum struct work with an empty parameter pack

本文关键字:包一起 一起 工作 参数 我的 何使 sizeof sum 结构      更新时间:2023-10-16

我有这个可变参数结构来确定传入的所有类型的大小之和:

template <typename U, typename... T> struct TotalSizeOf 
: std::integral_constant<size_t, sizeof(U) + TotalSizeOf<T...>::value> {};
template <typename U> struct TotalSizeOf<U> 
: std::integral_constant<size_t, sizeof(U)> {};

用法:TotalSizeOf<double, int, char>::value

问题是,我如何修改它以允许它在空参数包上工作,返回0;

例如TotalSizeOf<>::value

目前,我收到错误error: wrong number of template arguments (0, should be at least 1)

我只有 C++14 可用。

你只需要专注于<>

例:

template < typename... T> struct TotalSizeOf;
template < typename U, typename... T> struct TotalSizeOf<U, T...>
: std::integral_constant<size_t, sizeof(U) + TotalSizeOf<T...>::value> {};
template <> struct TotalSizeOf<> :
std::integral_constant<size_t, 0 > { };
int main()
{
std::cout << TotalSizeOf< int, char>::value << std::endl;
std::cout << TotalSizeOf< char>::value << std::endl;
std::cout << TotalSizeOf< >::value << std::endl;
}

使用 C++17,您可以使用折叠表达式无需复杂的模板元编程即可获得它:

#include <iostream>
#include <type_traits>
template<class... T> 
struct TotalSizeOf: std::integral_constant<std::size_t, (0 + ... + sizeof(T))> {};
int main()
{
std::cout << TotalSizeOf< int, char>::value << std::endl;
std::cout << TotalSizeOf< char>::value << std::endl;
std::cout << TotalSizeOf< >::value << std::endl;
}

这在编译时也应该更有效(当然在运行时,这些是相同的(。

PS:只是阅读,你只有C++14,但会让它站在这里,因为我认为很高兴看到,我们不太被迫在较新的C++版本中做笨拙的TMP。

附录:不如 C++17 优雅,但C++14 且几乎无 tmp。

#include <iostream>
#include <type_traits>
#include <initializer_list>
constexpr size_t sum(std::initializer_list<size_t> arr) {
// Accumulate is sadly not constexpr in C++14
auto ret = 0ul;
for(auto i: arr) {
ret += i;
}
return ret;
}
template<class... T> 
struct TotalSizeOf: std::integral_constant<std::size_t, sum({sizeof(T)...})> {};
int main()
{
std::cout << TotalSizeOf< int, char>::value << std::endl;
std::cout << TotalSizeOf< char>::value << std::endl;
std::cout << TotalSizeOf< >::value << std::endl;
}