C++ const_cast usage instead of C-style casts

后端 未结 4 1531
长情又很酷
长情又很酷 2021-01-17 23:51

Why is the following?:

  const int i0 = 5;
//int       i1 = const_cast(i0);       // compilation error
  int       i2 = (int)i0;                           


        
相关标签:
4条回答
  • 2021-01-18 00:10

    According to CPP Reference, the result has to be pointer or references. When using pointer, the input also needs to be a pointer. For references, you can the variables as inputs, and reference as output. The page says:

    lvalue of any type T may be converted to a lvalue or rvalue reference to the same type T, more or less cv-qualified. Likewise, a prvalue of class type or an xvalue of any type may be converted to a more or less cv-qualified rvalue reference.

    meaning

    /* lvalue can be converted to lvalue or rvalue references  */
    int& test1 = const_cast<int&>(var);   // lvalue to l-ref; same works for class type
    int&& test2 = const_cast<int&&>(var); // lvalue to r-ref; same works for class type
    /* prvalues: restriction on built-in types to allow some compiler optimization */
    //int&& test5 = const_cast<int&&>(1);            // prvalue of built-in not allowed
    A&& test6 = const_cast<A&&>(A());                // prvalue of class type allowed
    /* xvalue can be converted to rvalue references */
    int&& test8 = const_cast<int&&>(std::move(var)); //xvalue of built-in
    A&& test8 = const_cast<A&&>(std::move(A()));     // xvalue of class
    
    0 讨论(0)
  • 2021-01-18 00:14

    It's an error because the standard says it's not allowed. The standard enumerates the kinds of conversions that const_cast is allowed to do, and it disallows anything not on the list. It allows the following:

    • Pointers
    • References
    • Member-pointers

    Since your types aren't any of those, they're not allowed.

    On the bright side, the examples you gave don't need const_cast, either.

    0 讨论(0)
  • 2021-01-18 00:17
      const int i0 = 5;
    //int       i1 = const_cast<int>(i0);       // compilation error
      int       i2 = (int)i0;                   // okay
    
      int       i3 = 5;
    //const int i4 = const_cast<const int>(i3); // compilation error
      const int i5 = (const int)i3;             // okay
    

    The compilation errors are caused because you don't cast const away/add const. Instead, you copy i0. For that operation, no cast is required at all:

    int i1 = i0;
    const int i4 = i3;
    

    The type you cast to should actually be a pointer or reference. Otherwise, using const_cast doesn't make sense since you could straight copy it. For pointers, for example, you can cast away the const, because dereferencing the pointer will yield another type for a const T* (yields const T) than for a T* (yields T). For references, the same is true: T& will access the object using another this pointer type than using const T&. Now what you really wanted to archive:

      const int i0 = 5;
    //int &     i1 = const_cast<int&>(i0);      // okay (but dangerous)
      int &     i2 = (int&)i0;                  // okay (but dangerous)
    
      int       i3 = 5;
    //const int&i4 = const_cast<const int&>(i3); // ok now and valid!
      const int&i5 = (const int&)i3;             // okay too!
    

    The above can lead to undefined behavior, when you write to an originally const object through a reference to non-const (actually, merely casting and reading it isn't undefined behavior in itself. But if you're casting away const, you may also write to it, which then yields the undefined behavior)

    0 讨论(0)
  • 2021-01-18 00:27

    For the first error. const_cast can only be used on pointer or reference types. "int" is neither. This may or may not be the C++ standard (couldn't find a good reference). But it is the case for certain implementations such as MS's C++ compiler.

    For the second error. const_cast can only be used to remove a const or volatile qualifier not add it.

    Reference: http://msdn.microsoft.com/en-us/library/bz6at95h(VS.80).aspx

    0 讨论(0)
提交回复
热议问题