从'void *'转换为'const std :: string *&'必须让所有中间指针const限定

时间:2018-03-10 14:07:29

标签: c++ casting clang

我有这段代码使用iostreams'pwordvoid*&来存储各种类型的标志作为指针。由于#include <iostream> #include <string> using namespace std::literals; void*& pword() { static void* ptr; return ptr; } const std::string*& sword() { return (const std::string*&) pword(); } int main() { const auto s1 = "foo"s; const auto s2 = "bar"s; sword() = &s1; std::cerr << *sword() << '\n'; sword() = &s2; std::cerr << *sword() << '\n'; } 公开了一个void*,我有一个简单的包装器来通过一个旧的C cast来公开存储的类型。但是从第5版开始,clang发出了一个我不太了解的警告。我不明白如何避免它。简单的测试用例如下:

clang++-mp-devel -std=c++17 -Wcast-qual foo.cc && ./a.out 
foo.cc:14:32: warning: cast from 'void *' to 'const std::string *&' (aka 'const basic_string<char,
      char_traits<char>, allocator<char> > *&') must have all intermediate pointers const qualified
      to be safe [-Wcast-qual]
  return (const std::string*&) pword();
                               ^
1 warning generated.
foo
bar

我收到的警告(似乎忘记了const std::string*& sword2() { return static_cast<const std::string*&>(pword()); } 上的引用):

foo.cc:19:10: error: non-const lvalue reference to type 'const std::string *' (aka 'const
      basic_string<char, char_traits<char>, allocator<char> > *') cannot bind to a value of
      unrelated type 'void *'
  return static_cast<const std::string*&>(pword());
         ^                                ~~~~~~~

另外,我没有看到如何使用C ++强制转换而不是C全能转换。明显的尝试:

{{1}}

以错误结束我不明白。该错误似乎暗示编译器可能觉得有必要在某处插入副本,打破引用链,但我不知道在哪里以及为什么。

{{1}}

1 个答案:

答案 0 :(得分:1)

这相当于一个着名的事实,即您无法将char**转换为const char** - 因为它会允许

const char cc='a';
const char *cp=&cc;
char *p;
const char **pp=&p;  // error in question
*pp=cp;  // i.e., p=&cc;
*p='z';  // oops

在这种情况下,通过将void*描述为const std::string*,您可以存储指向常量字符串的指针(就像您一样),然后在{{1}上使用static_cast获取指向字符串的非void*指针。

答案是使用const 添加 const_cast然后(如HolyBlackCat所说)const(然后小心不要尝试修改字符串!):

reinterpret_cast

除了const-correctness之外,我现在还不记得是否通过这样的const std::string*& sword() { return reinterpret_cast<const std::string*&>(const_cast<const void*&>(pword())); } T*存储到void*变量中是明确的行为;然而,它是人们期望在常见实现中工作的东西。