Passing temporaries as non-const references in C++

前端 未结 3 1069
长情又很酷
长情又很酷 2021-02-03 11:41

I have the following piece of code, as an example dec_proxy attempts to reverse the effects of the increment operator upon the type that is executed in a complex function call f

相关标签:
3条回答
  • 2021-02-03 12:09

    What you try to do is to pass a rvalue (your new dec_facade<int>(i)) as an lvalue reference, which explains why it doesn't work.

    If you compiler support it, you can use rvalue references, using && type modifier : (Support for rvalue reference could be enabled by switching on C++0x or C++11 [partial] support)

    template<typename T>
    void foo(T& t)
    {    
        ++t;
    }
    template<typename T>
    void foo(T&& t)
    {    
        ++t;
    }
    

    But that only one part of the problem. What you try to do, is to pre-increment a temporary value! That's non-sense, as it won't live after that call. Your object will be increment, then destroyed.


    One other solution would be to remove the & from your function definition, which would permit it to accept any parameter. But that's perhaps not what you want.

    0 讨论(0)
  • 2021-02-03 12:13

    Taking Stephen's advice, you should look at the answer to How come a non-const reference cannot bind to a temporary object? and simply add a member function that returns a reference dec_proxy, e.g.:

    dec_proxy &ref() { return *this; }

    and call foo:

    foo(
        dec_proxy<int>(i).ref(), 
        dec_proxy<double>(j).ref(), 
        dec_proxy<short>(k).ref());
    

    I'm pretty sure that compiles.

    0 讨论(0)
  • 2021-02-03 12:14

    Thanks to MSN, the solution:

    I don't think it is correct by adding the function template template<typename T> dec_proxy_impl<T>& dec_proxy(T&t).

    What it did is just cheating compiler. It will result in runtime error. The function foo requires the lvaue or lvalue reference. But template<typename T> dec_proxy_impl<T>& dec_proxy(T&t) doesn't return a valid lvalue reference. In the implementation, it creates a temporary object, and returns it. After the function call finishes, the temporary object will be destroyed. So the value reference passed into the function foo is wrong. Actually the referenced object has already been destroyed. The ++t;++s;++r are trying to access the invalid objects. The behavior is undefined.

    The solution from MSN is correct. The life time of the object dec_proxy<int>(i) is from its declaration to the end of the function call. It makes sure the parameter in the function foo is valid.

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