[英]Why does static_cast not use the conversion operator to pointer to const?
從我的包裝類Pointer<Base>
我只想返回指向const的指針: Base const *
。
將Pointer<Base>
為Derived const *
出現編譯錯誤:
錯誤C2440:'static_cast':'指針'無法轉換為'const Derived *'
(翻譯自德語VS2012)
struct Base { };
struct Derived : public Base { };
template <typename T>
class Pointer {
public:
Pointer(T *t = nullptr) : p(t) { }
//operator T*() { return p; }
operator T const *() const { return p; }
template <typename U>
inline U staticCast() const { return static_cast<U>(d); }
private:
T *p;
};
int main(int argc, char *argv[]) {
Derived d;
Pointer<Base> p(&d);
Derived const *pd = static_cast<Derived const *>(p);
}
如果我啟用轉換operator T*() { return p; }
operator T*() { return p; }
它的工作原理。
為什么static_cast
不使用const轉換運算符?
或者更具體地說,因為
Derived const *pd = static_cast<Derived const *>(static_cast<Base const *>(p));
作品:
為什么static_cast
可以隱式地轉換為Base *
,但不能轉換為Base const *
,即使后者足夠用於轉換目標類型?
標准說 :
如果存在從表達式到new_type的隱式轉換序列,或者如果從表達式直接初始化對象或類型new_type的引用的重載解析將找到至少一個可行函數,則static_cast(expression)返回初始化為的虛構變量Temp if by new_type Temp(expression);,可能涉及隱式轉換 ,調用new_type的構造函數或調用用戶定義的轉換運算符 。
[由我強調]
解決方法
由於這似乎是一個VisualStudio錯誤,我將使用一個變通方法,通過模板化成員函數staticCast()
(參見上面的示例代碼),使用如下:
Derived const *pd = p.staticCast<Derived const *>();
要僅允許轉換為U const *
,請使用SFINAE:
template <typename U>
struct is_pointer_to_const
{
static const bool value = std::is_pointer<U>::value
&& std::is_const<typename std::remove_pointer<U>::type >::value;
};
template <typename U>
inline U staticCast(typename std::enable_if<is_pointer_to_const<U>::value >::type* = 0) const
{ return static_cast<U>(d); }
template <typename U>
inline U staticCast(typename std::enable_if<!is_pointer_to_const<U>::value >::type* = 0) const
{ static_assert(false, "Type is not a pointer to const"); return U(); }
只允許一次轉換,因此您可以轉換為Base
,但之后無法將其轉換為Derived
。
所以你必須使用兩個連續的演員表。 無論如何它更安全,因為你聲明你知道你正在從Base
轉換為Derived
。 您永遠不應該從基類到派生類的隱式轉換。
當您嘗試轉換Pointer<Base>*
---(1)---> Base const*
---(2)---> Derived const*
,您需要分兩步處理:
Pointer<Base>::operator Base const*
例如
Base const* pb = static_cast<Base const *>(p);
Derived const *pd = static_cast<Derived const*>(pb);
現場演示 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.