我正在尝试扩展用于计算模板包类型大小的代码,以便能够获取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;
}
虽然干杯和hth。-Alf对我的问题进行了评论,准确地描述了此代码,我在看到评论之前就亲自编写了该代码。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句