返回对const stuct的(指针类型)成员的引用:从左值到右值的转换

时间:2018-08-08 00:30:47

标签: c++ implicit-conversion value-categories

鉴于以下代码,GCC提供了一些意外的错误和警告。我正在尝试通过引用返回结构的成员,这就是说我正在返回一个临时对象!另外,尝试修复此功能时,它抱怨值类别转换错误?据我所知,在任何情况下,对左值对象的成员访问都应产生一个左值,因此此代码应首先起作用。怎么了?

代码:(live on Coliru

const struct {
    int* iptr = nullptr;
} cnst_struct;

const int* const& return_temporary_warning() {
    return cnst_struct.iptr;
}

const int*& value_cat_convert_error() {
    return cnst_struct.iptr;
}

产品(GCC):

main.cpp: In function 'const int* const& return_temporary_warning()':
main.cpp:8:24: warning: returning reference to temporary [-Wreturn-local-addr]
     return cnst_struct.iptr;
                        ^~~~
main.cpp: In function 'const int*& value_cat_convert_error()':
main.cpp:16:24: error: cannot bind non-const lvalue reference of type 'const int*&' to an rvalue of type 'const int*'
     return cnst_struct.iptr;

            ~~~~~~~~~~~~^~~~

1 个答案:

答案 0 :(得分:3)

通过使struct成员成为指向const的指针,可以使所讨论的代码编译时没有错误或警告:

const struct {
    const int* iptr = nullptr;
} cnst_struct;

或者,通过使函数返回非常量引用。

这里的问题(虽然微妙)是iptr成员与返回的引用的衰减类型不是完全相同的类型,因此尝试进行转换。有一个,即int*-> const int*,但是此转换的结果是右值,因此所有警告和错误。

另外,Clang会产生不同的警告,这也许会更有用:

main.cpp:8:12: warning: returning reference to local temporary object [-Wreturn-stack-address]
    return cnst_struct.iptr;
           ^~~~~~~~~~~~~~~~
main.cpp:16:12: error: non-const lvalue reference to type 'const int *' cannot bind to a value of unrelated type 'int *const'
    return cnst_struct.iptr;
           ^~~~~~~~~~~~~~~~