获取std :: vector的大小(通过扩展可变参数模板函数,使其仅与参数类型一起使用以与参数一起使用)

飞行帽

我正在尝试扩展用于计算模板包类型大小的代码,以便能够获取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函数Tsstd::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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章