本文介绍了可以reinterpret_cast(或任何演员)将xvalues转换为lvalue?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码是否合法(通过C ++ 11和/或C ++ 14标准)?

Is the following code legal (by C++11 and/or C++14 standard(s))?

#include <iostream>
#include <utility>

using namespace std;

void foo(int &a) {
    cout << a << endl;
}

int main() {
    foo(reinterpret_cast<int &>(move(5)));
}




  • 如果是,是否未定义行为? / li>
  • 如果不是未定义的行为,我甚至可以在内它变成UB?

  • 它在clang 3.5上编译,而不是在gcc 4.9上编译。
    GCC错误:

    It compiles on clang 3.5, not on gcc 4.9.GCC error:

    ➤ g++-4.9 -std=c++1y sample.cpp -o sample
    sample.cpp: In function 'int main()':
    sample.cpp:11:40: error: invalid cast of an rvalue expression of type 'std::remove_reference<int>::type {aka int}' to type 'int&'
         foo(reinterpret_cast<int &>(move(5)));
                                            ^
    



    EDIT



    FYI,一个定制的铸造,比以前更少毛,它工作在C ++ 11为GCC和Clang,将是以下 lvalue 函数:

    #include <iostream>
    
    namespace non_std {
        template <typename T>
        constexpr T &lvalue(T &&r) noexcept { return r; }
    }
    
    void divs(int &a, int &b) {
        int t = a;
        a /= b;
        b /= t;
    }
    
    int main() {
        using namespace std;
        using namespace non_std;
    
        int i_care_for_this_one = 4;
        divs(i_care_for_this_one, lvalue(2));
        cout << i_care_for_this_one << endl;
    }
    


    推荐答案

    / strong>代码在C ++ 11中是不成形的。下面的答案是为C ++ 14。

    Update: The code is ill-formed in C++11. Answer below is for C++14. See note at the end of this answer.

    我相信此代码格式正确定义良好。这是为什么。

    I believe this code is both well-formed and well-defined. Here's why.

    std :: move 的结果是xvalue [1] ;并将标量转换为一个左值引用 reinterpret_cast 似乎被标准的措辞允许:

    The result of std::move is an xvalue [1], which is a type of glvalue; and converting a glvalue to an lvalue reference with reinterpret_cast appears to be allowed by the wording of the standard:

    由于 int 的指针可以转换为指向 int reinterpret_cast 也是允许的。该标准没有说明目标类型是否是一个左值引用或右值引用。

    Since "pointer to int" can be converted to "pointer to int", this reinterpret_cast is also allowed. The standard doesn't say anything about whether the destination type has to be an lvalue reference or rvalue reference.

    转换的结果是由上述段落:它引用与源glvalue相同的对象 - 即,值为 5的临时 int 对象。 ([dcl.init.ref]指定当一个prvalue绑定到一个引用时创建一个临时变量。)

    The result of the cast is well-defined by the paragraph above: it refers to the same object as the source glvalue---that is, a temporary int object with the value 5. ([dcl.init.ref] specifies that a temporary is created when a prvalue is bound to a reference.)

    通过 int& 也不违反任何别名规则,因为原始对象也是 int 类型。事实上,我相信,通过这样获得的左值来修改临时值也是很明确的。

    Accessing the value through the int& also doesn't violate any aliasing rules since the original object was also of type int. In fact I believe it would even be well-defined to modify the temporary through the lvalue thus obtained.

    注意:措辞表示左值表达式,而不是glvalue表达式。与glvalue expression的措辞是从N3936,这是C ++ 14的最后工作草案。我不是标准化过程如何工作的专家,但我相信这意味着左值到glvalue的变化已经被委员会投票,当ISO发布C ++ 14标准时,它会非常类似于上面所说的。

    Note: The C++11 wording says "lvalue expression", not "glvalue expression". The wording with "glvalue expression" is from N3936, which is the final working draft for C++14. I'm not an expert in how the standardization process works, but I believe this means that the change of "lvalue" to "glvalue" was already voted in by the committee, and when ISO publishes the C++14 standard, it's going to be pretty similar to what it says above.

    [1]除了在极少数情况下,参数是一个函数;在这种情况下,结果是一个左值,因为没有函数rvalues。

    [1] Except in the rare case in which the argument is a function; in that case the result is an lvalue, since there are no function rvalues.

    这篇关于可以reinterpret_cast(或任何演员)将xvalues转换为lvalue?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 01:59