簡體   English   中英

為什么static_cast不使用轉換運算符指向const?

[英]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* ,您需要分兩步處理:

  1. Pointer<Base>::operator Base const*
  2. 沮喪。

例如

Base const* pb = static_cast<Base const *>(p);
Derived const *pd = static_cast<Derived const*>(pb);

現場演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM