constant references with typedef and templates in c++

前端 未结 5 1396
伪装坚强ぢ
伪装坚强ぢ 2020-11-28 13:45

I heard the temporary objects can only be assigned to constant references.

But this code gives error

#include     
template

        
相关标签:
5条回答
  • 2020-11-28 14:02

    Your code gives error because the const qualifier in const ref error is just ignored because 8.3.2/1 says

    Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef (7.1.3) or of a template type argument(14.3), in which case the cv-qualifiers are ignored.`

    So error has type int& not const int& .

    0 讨论(0)
  • 2020-11-28 14:02

    To maintain consistency with the Right Left Rule, I prefer to use 'cv' qualifiers like so.

    int const x = 2; // x is a const int (by applying Right Left rule)
    
    int const *p = &x;  // p is a pinter to const int
    

    In your example, I would write const ref error = check<int>(); like so

    ref const error = check<int>(); // parsed as error is a const reference to an integer
    

    As @Prasoon Saurav pointed out, cv qualifiers are ignored when introduced through typedef because as @GMan also says, that cv qualified references are ill-formed.

    Therefore the declaration is effectively as below, which of course is an error.

       int &error = check<int>(); 
    

    Check out this for more information.

    0 讨论(0)
  • 2020-11-28 14:14

    This:

    typedef int& ref;
    const ref error;
    

    Doesn't do what you think it does. Consider instead:

    typedef int* pointer;
    typedef const pointer const_pointer;
    

    The type of const_pointer is int* const, not const int *. That is, when you say const T you're saying "make a type where T is immutable"; so in the previous example, the pointer (not the pointee) is made immutable.

    References cannot be made const or volatile. This:

    int& const x;
    

    is meaningless, so adding cv-qualifiers to references has no effect.

    Therefore, error has the type int&. You cannot assign a const int& to it.


    There are other problems in your code. For example, this is certainly wrong:

    template<class t>
    t const& check()
    {
        return t(); //return a temporary object
    }
    

    What you're doing here is returning a reference to a temporary object which ends its lifetime when the function returns. That is, you get undefined behavior if you use it because there is no object at the referand. This is no better than:

    template<class t>
    t const& check()
    {
        T x = T();
        return x; // return a local...bang you're dead
    }    
    

    A better test would be:

    template<class T>
    T check()
    {
        return T();
    }
    

    The return value of the function is a temporary, so you can still test that you can indeed bind temporaries to constant references.

    0 讨论(0)
  • 2020-11-28 14:23

    It's a very common mistake for English speaking people, because of the way the English grammar works.

    I consider it extremely unfortunate that the C++ syntax would allow both:

    const int // immutable int
    int const // immutable int
    

    to have the same meaning.

    It doesn't make it easier, really, and isn't composable since:

    const int* // mutable pointer to immutable int
    int* const // immutable pointer to mutable int
    

    certainly do NOT have the same meaning.

    And this, unfortunately for you, what kicks in here, as @GMan explains.

    If you wish to avoid this kind of error in the future, take the habit of qualifying your types (const and volatile) on their right, then you'll be able to treat a typedef as simple text replacement.

    0 讨论(0)
  • 2020-11-28 14:25

    This is compiled:

    typedef const int& ref; 
    ref error = check<int>(); 
    

    VC++ compiler gives some explanation of your error: qualifier applied to reference type; ignored. Reference type must be declared as constant, const cannot be applied later.

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