获取 std::vector 的大小(通过扩展专门使用参数类型的可变参数模板函数来处理参数)
Getting size of std::vector (by extending variadic template functions working exclusively with parameter types to work with arguments)
我正在尝试扩展计算模板包类型大小的代码,以便能够获取std::vector<T>
实例的大小(我对向量大小的概念是std::vector<T>::size() * sizeof(T)
(。这是原始代码:
template <class T>
constexpr size_t getSize_single()
{
return sizeof(T);
}
// specialized case
template<>
constexpr size_t getSize_single<double>()
{
return SIZEOF_DOUBLE;
}
template <class... Ts>
size_t getSize()
{
// handles the case of Ts being empty
std::initializer_list<size_t> l{getSize_single<Ts>()...};
size_t sum = 0;
for(auto s : l) sum += s;
return sum;
}
我像这样使用它
template <class ...T>
void foo(T... arg)
{
std::cout << getSize<T...>() << std::endl;
}
// main
foo(11.123456789, 1.12345, 2.12345, 3.12345);
我对将其扩展到与std::vector<T>
一起工作的看法如下:
由于我们需要 获取std::vector<T>
实例的大小 ,我们需要访问它,我们通过将其传递给 getSize()
来实现,这会将其更改为
template <class ...T>
void foo(T... arg)
{
std::cout << getSize(arg...) << std::endl;
}
// main
foo(11.123456789, std::vector<double>{1.12345, 2.12345, 3.12345});
然后
template <class T>
constexpr size_t getSize_single()
{
return sizeof(T);
}
template<>
constexpr size_t getSize_single<double>()
{
return SIZEOF_DOUBLE;
}
// arg_tag_val<T> hack for std::vector to work
template <typename T> struct arg_tag_val {const T &t;};
template <class T>
constexpr size_t getSize_single(arg_tag_val<T>)
{
return getSize_single<T>();
}
template<>
constexpr size_t getSize_single<double>(arg_tag_val<double>)
{
return getSize_single<double>();
}
template<>
constexpr size_t getSize_single<float>(arg_tag_val<float>)
{
return getSize_single<float>();
}
template <class T>
size_t getSize_single(arg_tag_val<std::vector<T>> v)
{
return v.t.size() * getSize_single<T>();
}
template <class... Ts>
size_t getSize(const Ts&... arg)
{
// handles the case of Ts being empty
std::initializer_list<size_t> l{getSize_single<Ts>(arg_tag_val<Ts>{arg})...};
size_t sum = 0;
for(auto s : l) sum += s;
return sum;
}
但是它失败了,因为在底部getSize
函数中Ts
std::vector<double>
,getSize_single
被调用为getSize_single<std::vector<double>>(arg_tag_val<std::vector<double>>{vec})
,它调用constexpr size_t getSize_single(arg_tag_val<T>)
而不是size_t getSize_single(arg_tag_val<std::vector<T>> v)
。
我被困在这里,不知道如何让它工作,因此寻求帮助。
我仅限于 C++11。
看起来我的第一个想法完全是过度设计的。如果我们摆脱arg_tag_val
参数包装器并使用实际参数,那么一切正常。
template <class T>
size_t getSize_single(T&)
{
return sizeof(T);
}
// specialized case
template<>
size_t getSize_single<double>(double&)
{
return SIZEOF_DOUBLE;
}
template <class T>
size_t getSize_single(std::vector<T>& v)
{
size_t size = 0;
if (v.size() > 0) {
size += v.size() * getSize_single(v[0]);
}
return size;
}
template <class... Ts>
size_t getSize(Ts&... arg)
{
// handles the case of Ts being empty
std::initializer_list<size_t> l{getSize_single(arg)...};
size_t sum = 0;
for(auto s : l) sum += s;
return sum;
}
虽然干杯和呵呵。 - Alf 评论了我的问题,准确地描述了这段代码,我在看到评论之前自己写的。
相关文章:
- 在不传递参数数量且只有3个点的情况下,如何使用变差函数
- 如何使用可变参数模板强制转换每个变体类型
- 关于如何在具有单个参数的变体构造中选择替代方案?
- 调用参数排列不变函数 f(i++, i++)
- 参数归纳与标准::变体
- 模板化回调参数的逆变,如 C# 中的逆变
- 如何在没有参数包的情况下编写变差函数
- 通过具有嵌套类的工厂类获取多个变异类模板参数包
- 获取模板参数的成员变量值列表
- 保留短 lambda 用作函数的中间参数,使用 clang 格式保持不变
- 如何定义变体<x,y,z>提取模板参数的子类型
- 正确对齐内存模板,参数顺序不变
- 递归中不同参数类型的变元模板函数
- 通过函数指针传递给变差函数的参数会更改其值
- 提升预定义为带有参数的全局 lambda 的变体访问者
- 使用可变参数模板参数提升变体访问者
- boost ::变体 - 为什么模板参数比const字符串参数具有更高的优先级
- 将变参数包中的值加载到临时数组中
- 使用额外参数提升变体访客
- 正在将动态数组元素解析为参数?(变音符)