微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何计算C ++模板函数中有效指针元素的总数?

如何解决如何计算C ++模板函数中有效指针元素的总数?

我最近在C#和Python方面具有丰富的经验之后开始学习C ++。

我试图创建一个接受指针参数的函数模板,然后迭代其值,直到下一个指针元素不再有效为止。理想情况下,我希望该函数接受一个通用指针参数。值得一提的是,我无法直接利用基础数组来计算其大小。

我能够为指针的指针实现相同的概念,下面将其包括在内:

template<class T>
inline constexpr size_t len(const T *pptr[])
{
    if (pptr == nullptr) { return (const size_t)size_t(); }
    const T **begptr = &pptr[0];

    while (*pptr != nullptr)
    {
        pptr++;
    }
    return (const size_t)(pptr - begptr);
}

尝试为普通指针(int *char *等)实现相同概念的问题是,一旦计数器不存在,我不知道如何有条件地中断循环有效期更长。我希望我能够检查指针地址是否有效,然后相应地中断以使最终计数准确。

到目前为止,我拥有所需功能的伪代码

template<class T>
inline constexpr size_t len(const T *ptr)
{
    if (ptr == nullptr) { return (const size_t)size_t(); }
    const T *begptr = &ptr[0];

    while (/*Pointer is valid*/)
    {
        ptr++;
    }
    return (const size_t)(ptr - begptr);
}

那么我可以通过循环准确地计算有效元素的数量吗?我愿意使用其他方法,我真的只想要某种模板函数,该函数可以接受通用指针并准确计数元素的数量

在此先感谢大家的时间和帮助,我真的很感激。

解决方法

template<class T,size_t N>
constexpr size_t size(const T(&)[N])
{
    return N;
}

template<class T>
constexpr size_t len(const T& a)
{
    return std::distance(std::begin(a),std::find(std::begin(a),std::end(a),nullptr));
}

https://godbolt.org/z/r7MhT4

,

您尝试使用len()函数来寻找nullptr元素的操作只能通过以空字符结尾的指针数组来实现,例如:

int* arr[3];
arr[0] = ... some pointer ...;
arr[1] = ... some pointer ...;
arr[2] = nullptr;

size_t arr_len = len(arr); // returns 3

无法在数组中包含终止符nullptr,并且函数的循环最终将进入周围的内存,从而导致未定义的行为

int* arr[3];
arr[0] = ... some pointer ...;
arr[1] = ... some pointer ...;
arr[2] = ... some pointer ...; // <-- not nullptr!

size_t arr_len = len(arr); // undefined behavior!

但是,您的len()函数按原样不能对非指针数组执行相同的操作,例如:

int arr[3];
arr[0] = ... some value ...;
arr[1] = ... some value ...;
arr[2] = ... some value ...; // <-- can't assign nullptr here!

size_t arr_len = len(arr); // DOES NOT WORK

您不能将非指针与nullptr进行比较,但可以将它们与默认初始化的T进行比较。因此,您将不得不重新编写该函数。您可以传入分配的数组长度作为第二个参数,例如:

template<class T>
inline constexpr size_t len(const T pptr[],size_t nump)
{
    if (!pptr) return 0;

    const T *begptr = pptr;

    while ((nump > 0) && (*pptr != T{}))
    {
        ++pptr;
        --nump;
    }

    return (pptr - begptr);
}
int arr[5];
arr[0] = ... some value ...;
arr[1] = ... some value ...;
arr[2] = 0;
arr[3] = ...;
arr[4] = ...;

size_t arr_len = len(arr,5); // returns 3

或者,您可以通过引用获取 数组,而不是通过指针获取 ,这样就不会丢失其大小信息,例如:

template<class T,size_t N>
inline constexpr size_t len(const T (&pptr)[N])
{
    const T *begptr = &pptr[0];

    for(size_t i = 0; i < N; ++i)
    {
        if (*pptr == T{}) break;
        ++pptr;
    }

    return (pptr - begptr);
}
int arr[5];
arr[0] = ... some value ...;
arr[1] = ... some value ...;
arr[2] = 0;
arr[3] = ...;
arr[4] = ...;

size_t arr_len = len(arr); // returns 3

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。