【问题标题】:reason for pointer to a const pointer when using static_cast使用 static_cast 时指向 const 指针的原因
【发布时间】:2020-01-26 11:23:46
【问题描述】:

我试图从书中解决一个练习,但我在 static_cast 上失败了。我使用了 cstdlib 中的 qsort 方法。我必须将函数的参数转换为 C-String (const char*)。但我总是收到错误消息:stattic_cast from type 'const void*' to type 'const char**' casts away qualifiers。

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

最后一个 const 的原因是什么,它来自哪里?为什么我必须强制转换为指向 constant 指向 char const 的指针?

【问题讨论】:

    标签: c++ constants static-cast


    【解决方案1】:

    它来自原点指针。 static_cast 不能丢弃 const 限定符。所以你只能将void const* 转换为T const*

    现在,您的T 恰好是char const*。您可能被原始代码中的领先 const 误入歧途。它不适用于人们认为它适用的地方。

    【讨论】:

    • 你说的是对的,但是演员应该是const char*而不是const char**const char* const *首先不是OP的问题吗?
    • @Haatschii - qsort 提供指向数组元素的指针。该数组包含chat const* 作为元素,因此指针必须是char const* const*。至于 OP 的示例,我认为他们只是在初始化本地指针时忘记取消引用强制转换的结果。
    • 我已经尝试了很多东西:const char *c2 = (reinterpret_cast&lt;const char*&gt;(s2)); 会产生类似 std::cout &lt;&lt; "\n c2: " &lt;&lt; c2 &lt;&lt; '\n'; -&gt; ↔@@const char* const * 的结果。
    • @StoryTeller 我的错,没有意识到qsort 使用 void 指针调用比较函数(这在实现它的 C 函数时是有意义的)。感谢您的澄清。
    【解决方案2】:

    qsort 比较器参数是指向被比较元素的 const 版本的指针。在您的示例中,要比较的元素是 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
    }
    

    同样的模式也适用于非指针元素(例如整数元素)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-30
      • 2015-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多