Tro*_*yvs 0 c++ reference auto c++14
我在g ++ 7.3.1 -std = c ++ 14下面有一个简单的片段
#include<functional>
#include<iostream>
using namespace std;
struct S{
int m_i = 2;
auto& get2(){return ref(m_i);}
};
int main(){
S s;
s.get2()=4;
cout<<s.m_i<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它编译错误如下:
error: cannot bind non-const lvalue reference of type ‘std::reference_wrapper<int>&’ to an rvalue of type ‘std::reference_wrapper<int>’
auto& get2(){return ref(m_i);}
~~~^~~~~
In function ‘int main()’:
error: use of deleted function ‘std::reference_wrapper<_Tp>::reference_wrapper(_Tp&&) [with _Tp = int]’
s.get2()=4;
^
In file included from /usr/include/c++/7/bits/std_function.h:44:0,
from /usr/include/c++/7/functional:58,
from xxx.cpp:1:
/usr/include/c++/7/bits/refwrap.h:338:7: note: declared here
reference_wrapper(_Tp&&) = delete;
^~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
我知道,通过删除"ref"包装器,程序将被编译.我只想知道在这里使用"ref"有什么问题?
std::ref它不仅仅返回一个引用,它返回一个Reference Wrapper.具体来说,std::reference_wrapper<T>.因此,当你写作时return std::ref(m_i);,你没有返回int&,你正在返回std::reference_wrapper<int> &,这是对一个本身包含引用的悬空对象的引用.
只需按原样退回会员; 编译器会理解它是一个参考.
#include<functional>
#include<iostream>
//Don't use using namespace std;, it's bad practice
struct S{
int m_i = 2;
auto& get2(){return m_i;}
};
int main(){
S s;
s.get2()=4;
std::cout<<s.m_i<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
另外考虑使返回类型显式化,因为这不是一个你从使用中获益很多的情况auto.
#include<functional>
#include<iostream>
struct S{
int m_i = 2;
int& get2(){return m_i;}
};
int main(){
S s;
s.get2()=4;
std::cout<<s.m_i<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您共享的代码存在许多问题.
第一个问题是您返回对函数返回时将不再存在的对象的引用.std::ref返回一个std::reference_wrapper超出范围的东西.An std::reference_wrapper是一个对象,它提供了一些引用类型的功能,同时仍然表现得像一个对象.它具有移动语义,因此正确的用法是返回std::reference_wrapperby值.
#include<functional>
struct S {
int m_i = 2;
auto get2() { return std::ref(m_i); }
};
Run Code Online (Sandbox Code Playgroud)
虽然正如其他人指出的那样,std::ref但这里并不需要.您可以直接返回引用m_i.如果用户碰巧真的需要一个std::reference_wrapper,那么int他们可以std::ref使用m_i您提供的引用来调用自己.
struct S {
int m_i = 2;
int & get2() { return m_i; }
};
Run Code Online (Sandbox Code Playgroud)
但这不是您的代码唯一的问题.假设你修复了第一个问题并返回了你std::reference_wrapper的值,你仍然在滥用std::reference_wrapper::operator=.该运算符不会为引用的对象分配新值.相反,它重新引用引用以引用不同的实例.正确的用法是用来从以下方面get()获得适当的可分配:int&std::reference_wrapper
#include<functional>
#include<iostream>
struct S {
int m_i = 2;
auto get2() { return std::ref(m_i); }
};
int main() {
S s;
s.get2().get() = 4;
std::cout << s.m_i << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但错误信息呢?编译器看到唯一operator=存在的std::reference_wrapper是另一个std::reference_wrapper.因此,它试图通过尝试使用带有单个参数的构造函数来隐式转换4为std::reference_wrapper它可以的唯一方式.但是,不可能创建一个std::reference_wrapper像文字4(或一般的rvalues).它需要一个合适的左值来引用.通过声明一个接受对包装类型(在本例中为int)的rvalue引用并删除它的构造函数来防止这种情况.尝试使用该构造函数将产生您看到的错误.删除的函数是std::reference_wrapper<int>::reference_wrapper<int>(int&&)由编译器引入的转换调用的.
| 归档时间: |
|
| 查看次数: |
249 次 |
| 最近记录: |