简体   繁体   English

为什么此函数将'const char *'强制转换为'void * const'而不是'const void *'

[英]Why does this function cast 'const char*' to 'void* const' and not 'const void*'

This is a very stupid example I came up while working with threads in Windows to wrap a const_cast and a static_cast into one 这是一个非常愚蠢的示例,我在Windows中使用线程将const_caststatic_cast包装到一个线程中时static_cast

// Somewhere in the OS API
using function_t = void(*)(void *);
void create_thread(function_t function, void *params);

template <typename T, typename U>
T static_const_cast(U ptr) {
  return const_cast<T>(static_cast<const T>(ptr));
}

void thread_proc(const void* name) {
  // ...
}

void test() {
  const char *name = "name";
  void *params = static_const_cast<void *>(name); // Fails
  // void *params = const_cast<void *>(static_cast<const void *>(name));
  // Succeeds (what I want to achieve with static_const_cast)
  create_thread(reinterpret_cast<function_t>(thread_proc), params);
}

but it won't compile on Visual Studio 2017, so I tried gcc and clang on Godbolt thinking it should surely be able to compile, but still refuses to with the error message (from gcc 8.2): 但它无法在Visual Studio 2017上编译,因此我在Godbolt上尝试了gcc和clang,认为它肯定可以编译,但仍然拒绝错误消息(来自gcc 8.2):

error: invalid static_cast from type 'const char*' to type 'void* const'
                                                           ^^^^^^^^^^^^^

Why does it try to cast to void* const instead of const void* as expected? 为什么它会尝试强制转换为void* const而不是预期的const void* Is there something obvious I am missing? 有什么明显的我想念的东西吗?

Why does this function cast 'const char*' to 'void* const' and not 'const void*' 为什么此函数将'const char *'强制转换为'void * const'而不是'const void *'

Because you used void * as the template argument, and when you apply const to that, it becomes void * const . 因为您使用void *作为模板参数,并且在将const应用于模板参数时,它将变为void * const void * is a pointer (to non-const object), and making a pointer const results in a const pointer, not a (non-const) pointer to const object. void *是一个指针(指向非const对象),将指针设为const会导致const指针,而不是指向const对象的(非const)指针。

You could do something like this to achieve what you wanted: 您可以执行以下操作来实现所需的功能:

return const_cast<T>(
    static_cast<std::remove_pointer_t<T> const*>(ptr)
);

However, I recommend instead to use a custom class to wrap the data that you send to the thread. 但是,我建议改用自定义类包装发送到线程的数据。 Also, don't cast the function type. 另外,请勿强制转换函数类型。 Use a function with void* argument, and cast the argument within the function. 使用带有void*参数的函数,并将参数转换为函数。

struct params_t {
    const char *name;
};

static params_t params {"name"};

create_thread(thread_proc, &params);

No casts needed whatsoever (except obviously in the callback). 不需要任何强制转换(显然在回调中除外)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM