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



在C#和Python方面积累了丰富的经验后,我最近开始学习C++。

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

我能够为指针中的指针实现相同的概念,我在下面包含了它:

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);
}

那么,我有可能用循环准确地计算有效元素的数量吗?我对使用不同的方法持开放态度,我真的只想要某种接受通用指针并准确计算元素数量的模板函数。

提前感谢大家的时间和帮助,我真的很感激。

您试图用len()函数查找nullptr元素的操作只有在指针数组为null终止的情况下才可能,例如:

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
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

相关内容

  • 没有找到相关文章

最新更新