使用 static_cast 时指向常量指针的原因

reason for pointer to a const pointer when using static_cast

本文关键字:指针 常量 static cast 使用      更新时间:2023-10-16

我试图从一本书中解决一个练习,但我在static_cast上失败了。我使用了cstdlib的qsort方法。我必须将函数的参数转换为 C 字符串(常量字符*(。但我总是收到错误消息:从类型"const void*"到类型"const char**"stattic_cast丢弃限定符。

int scmp(const void *s1, const void *s2) {
const char *c1 = (static_cast<const char**>(s1));
const char *c2 = (static_cast<const char**>(s2));
....
}
const char *sfield[] = {"one", "two", "three", "four", "five"};
qsort(sfield, 10, 4, scmp);

解决方案如下

const char *c1 = *(static_cast<const char* const*>(s1));

最后一个常量的原因是什么,它来自哪里?为什么我必须投射到指向 char const 的常量指针的指针?

它来自源指针。static_cast不得丢弃常量限定符。所以你只能把void const*投到T const*.

现在,碰巧您的Tchar const*。您可能被原始代码中的领先const引入歧途。它不适用于人们可能认为适用的地方。

比较器参数qsort指向要比较的元素的常量版本的指针。在您的示例中,要比较的元素是const char *,因此指向 const 的指针const char * const *。 因此,代码的正确版本:

int scmp(const void *s1, const void *s2) 
{
auto pc1 = static_cast<const char * const *>(s1);
auto pc2 = static_cast<const char * const *>(s2);
char const *c1 = *pc1;
char const *c2 = *pc2;
return strcmp(c1, c2);  // or whatever
}

如果您愿意,您可以取消pc1pc2并将*运算符应用于强制转换的结果。

也许您错误地认为参数是要比较的元素,而实际上它们是指向要比较的元素的指针。

如果仍然不清楚,那么为元素类型使用符号名称可能会有所帮助:

using ELEMENT_T = const char *;
int scmp(void const *s1, void const *s2) 
{
auto pc1 = static_cast<ELEMENT_T const *>(s1);
auto pc2 = static_cast<ELEMENT_T const *>(s2);
ELEMENT_T c1 = *pc1;
ELEMENT_T c2 = *pc2;
return strcmp(c1, c2);  // or whatever
}

相同的模式也适用于不是指针的元素(例如整数元素(。