如何更简洁地实现保留输入左右值属性的模板函数?
如何更简洁地实现保留输入左右值属性的模板函数?
嘿,你的实现已经精准命中了完美转发的核心逻辑,但确实有更简洁的写法可以达到完全一样的效果!
在C++14及以后的标准里,我们可以利用decltype(auto)这个返回类型推导特性,省去尾置的decltype(t)部分,直接写出更紧凑的代码:
#include <vector> using namespace std; template<typename T> decltype(auto) foo(T &&t) { return std::forward<T>(t); } int main() { vector<int> v{0, 1}; vector<int> v0 = foo(v); // OK,拷贝构造 vector<int> &v1 = foo(v); // OK,绑定左值引用 vector<int> v2 = foo(vector<int>{0, 1}); // OK,利用右值构造 // vector<int> &v3 = foo(vector<int>{0, 1}); // 依然报错,符合预期 return 0; }
为什么这样可行?
decltype(auto)的作用是完全按照返回表达式的类型来推导返回值类型,它会完整保留表达式的引用属性和值类别:
- 当你传入左值
v时,std::forward<T>(t)是左值引用,decltype(auto)就会推导出左值引用类型,和你原来的decltype(t)效果一致; - 当你传入临时右值
vector<int>{0,1}时,std::forward<T>(t)是右值,decltype(auto)就会推导出对应的右值类型,完美保留了原对象的值属性。
这个简化版本和你最初的实现功能完全等价,而且代码更短、可读性更强。如果是在C++20环境下,甚至还可以用概念进一步约束,但对于这个需求来说,上面的写法已经足够简洁啦。
备注:内容来源于stack exchange,提问作者chaosink
相关产品推荐
相关产品推荐

