[英]static_cast from 'const char *' to 'void *' is not allowed
[英]static_cast const reference to void*
我有一個對 void* 的 const 引用:
void* p;
void* const& x = p;
我想將它轉換為對 T* 的 const 引用(對於某些struct T {};
)。 在我能想到的三種方法中,我默認的static_cast
選擇不起作用:
T* const& y = static_cast<T* const&>(x); // doesn't work
T* const& y = reinterpret_cast<T* const&>(x); // works
T* const& y = (T* const&) x; // works
GCC 給出以下錯誤:
error: invalid static_cast from type ‘void* const’ to type ‘T* const&’
T* const& y = static_cast<T* const&>(x);
我想了解它的含義,以及是否有辦法解決它。
評論和答案中有關於T* const&
(和void* const&
)是否為
T*
的 const 引用; 或者const T*
的引用。評論中的共識似乎是選項 2。但是從以下示例中,在我看來它是選項 1。
假設我有一個帶有非常量函數f()
T
類:
struct T
{
void f() {}; // NB: non-const
};
我們可以考慮兩種選擇:
const T* x;
T* const& y;
通過它們調用f()
會產生不同的效果:
x->f(); // compile-time error (passing ‘const T’ as ‘this’ argument discards qualifiers)
y->f(); // works fine
這不表明選項 1 是正確的嗎? 有人可以為我調和嗎?
您不能將引用綁定到任何其他類型(除了相同類型的較少 cv 限定版本或某些涉及通過特殊類型(如unsigned char&
)讀取單個字節的微妙事物)。 如果您使用reinterpret_cast
(包括通過 C 風格的強制轉換)強制執行該問題,則使用結果(而不是通過將其返回)是未定義的行為。
您可以(僅使用static_cast
)將void*
值轉換為T*
,並且您可以提供諸如
const auto y=[&] {return static_cast<T*>(p);};
這樣您就可以通過稍后在任何地方編寫y()
來跟蹤p
的當前值。 (由於它按值返回,因此您確實無法根據需要編寫y()=new T
。)
這就是語言轉換的工作方式。 這是一個簡單的,缺少概述的內容:
const_cast
在具有不同cv資格的類型之間轉換。 static_cast
用於安全轉換。 整數轉換,轉換運算符或轉換構造函數是static_cast
可以執行的一些示例。 dynamic_cast
適用於多態 reinterpret_cast
是不得已的選擇,通過重新解釋基礎位模式,基本上可以進行任何轉換。 reinterpret_cast
。 從void*
到T*
轉換(都保存cv)是有效的,前提是原始指針的類型為T*
又在指向的位置處存在類型為T
的對象。 如您所見,如果條件不成立,則轉換是“危險的”,即您擁有UB(無效程序)。 因此,您只能使用reinterpret_cast
做到這一點。
查看不想通過某個指針修改值的原始問題,以下應該有效。 模板化它應該給出相同的結果。 如果需要,請引入參考文獻,但結果相同。
void myfunc1(int* intptr)
{
(*intptr)++;
std::cout << "In myfunc1 "<< *intptr<<"\n";
}
void myfunc2(const int* intptr)
{
//(*intptr)++; //modification not possible
std::cout << "In myfunc2 " << *intptr << "\n";
}
int main()
{
int* val = new int;
*val = 32;
void* p = val;
std::cout << "Before myfunc1 " << *val << "\n";
myfunc1(static_cast<int*>(p));
std::cout << "After myfunc1 "<<*val<<"\n";
//no modification via pointer to const
const int* x = static_cast<const int*>(p);
myfunc2(x);
std::cout << "After myfunc2 " << *val << "\n";
沒有const
參考。 在C ++中, 引用是不可分配的(只能對其進行初始化)。 同樣, void* const&
並不意味着對void *
的const引用。 相反,它意味着對指向void的const指針的引用。 在下面的語句中,您只是初始化一個引用,因此您無需在static_cast
提及引用。
T* const& y = static_cast<T* const&>(x);
正確的形式是:
T* const& y = static_cast<T* const>(x);
更新#1
評論和答案中有一個討論,關於T * const&(和void * const&)是否為
1和2都不是。請注意const T*
與T* const
不同。 前者是指向const T的非const指針,而后者是指向非const T的const指針。因此, T* const&
表示對指向非const T的const指針的引用。
同樣關於以下示例,
struct T
{
void f() {}; // NB: non-const
};
給定const T* x;
,則無法調用x->f();
。 因為x
是指向const T的指針,但是函數f
需要一個非const T,所以您不能使用const變量來初始化非const變量,因為這會丟棄const限定符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.