这篇文章主要介绍了C++11万能引用和右值引用的方法的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++11万能引用和右值引用的方法文章都会有所收获,下面我们一起来看看吧。
正文
实际上,type&& 有两种不同的含义。
其中一种就是 右值引用。它仅仅会绑定右值,用于识别出可移对象。
另外一种含义,则表示既可以是右值引用,也可以是左值引用。这种双重特性使其可以绑定到右值,也可以绑定到左值。还可以绑定到const对象或非const对象,以及volatile对象,甚至可以绑定那些既带有const又带有volatile的对象,拥有很强的灵活性,这就是万能引用。
那么,既然以上两种含义都是 type&& 结构,那么如何来区分二者呢?
万能引用
万能引用通常会在两种场景现身:函数模板的形参 和 auto声明。
示例如下:
template<typename T> void f(T&& param); //param是个万能引用
auto && var2 = var1;
以上两种场景的共同之处,在于它们都涉及型别推导。
在模板f中,param的类型是推导得到的,而在var2的声明语句中,var2的类型也是推导得到的。
因为万能引用首先是个引用,所以初始化是必须的。万能引用的初始化物会决定它代表的是个左值还是右值引用,如果初始化物是左值,万能引用就会对应得到一个左值引用,同理,如果初始化物是右值,万能引用就会对应得到一个右值引用。
对于作为函数形参的万能引用而言,初始化物在调用处提供:
template<typename T> void f(T&& param);Widget w;f(w); //左值被传递给f,param的类型是Widget&,即左值引用f(std::move(w)); //右值被传递给f,param的类型是Widget&&,即右值引用
有一个需要注意的问题是,万能引用除了要涉及型别推导,还有一个条件必须限定,就是必须要是“T&&”结构才行。
而类似
template<typename T> void f(std::vector<T>&& param); //param是右值引用
这样的类型并不是万能引用,仅仅只是一个右值引用。
而且,如果有const修饰也不可能成为万能引用,比如:
template<typename T> void f(const T&& param); //param是右值引用
那么,位于模板内是不是就一定就会涉及到型别推导呢? 还真不能保证。看以下示例:
template <class T,class Allocator = allocator<T>>class vector{public: void push_back(T&& x); ...};
以上是来自C++标准中vector类
这里的push_back的形参具备万能引用的正确形式,但是在本示例中,并不涉及到类型推导。因为push_back作为vector本身的一部分,如果不存在特定的vector实例,则它也无从存在。该实例的具体类型完全决定了push_back的声明类型。
如:
std::vector<Widget> v;
会导致std::vector模板具现化为如下实例:
template <class Widget,class Allocator = allocator<Widget>>class vector{public: void push_back(Widget&& x); //右值引用 ...};
现在就能看清楚push_back并未涉及到类型推导。
而vector中的另外一个函数却涉及到了类型推导,如下:
template <class T,class Allocator = allocator<T>>class vector{public: template<class... Args> void emplace_back(Args&&... args); ...};
关于“C++11万能引用和右值引用的方法”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“C++11万能引用和右值引用的方法”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。