声明一个可以使用右值或左值引用的函数的正确方法是什么
What is the proper way to declare a function that can take either rvalue or lvalue reference?
假设我想要一个函数foo
,将左值或右值引用作为参数。
我可以将它分解为两个重载,分别使用左值和右值引用。
void foo(int& a){/*some impl*/} // lvalue ref
void foo(int&& a){foo(a);} // rvalue ref
int main(){
int a;
foo(a); // lvalue
foo(1); // rvalue
}
它确实有效,但相当冗长。我可以使用模板来改进它。
template<typename T>
void foo(T &&a) { /*some impl*/ }
int main(){
int a;
foo(a); // lvalue, T = int&
foo(1); // rvalue, T = int
}
对于二进制函数,模板需要使用两个模板参数。
template<typename T1, typename T2>
void foo(T1 &&a, T2 &&b) { /*some impl*/ }
int main(){
int a;
foo(a, a); // (lvalue, lvalue), T1 = int&, T2 = int&
foo(1, 1); // (rvalue, rvalue), T1 = int, T2 = int
foo(1, a); // (rvalue, lvalue), T1 = int, T2 = int&
foo(a, 1); // (lvalue, rvalue), T1 = int&, T2 = int
}
这是要走的路吗?有更好的方法吗?
我几乎没有任何使用cpp的经验,但我似乎怀疑我需要做这样的技巧,简单地说"不要复制传递的参数"。
我使用gcc 5.4.0
和-std=c++11
。
--更新1-
当我使用流库range(T&& lower, T&& upper)
方法时,我提出了这个问题,该方法同时使用T&&
参数。我可以将lvalue
或rvalue
参数都传递给函数,但这使我无法将例如0
和some_var
作为参数传递。无论作者使用T&&
参数的函数的原因是什么,我想知道是否有一种方法可以在不牺牲作者想要实现的任何目标的情况下,将声明扩展为使用混合的左值/右值参数。
--更新2-
如果参数为只读,则可以使用const &
(@RichardCritten)。
当您想在不复制的情况下修改/返回参数时,可以使用模板或@Yakk解决方案。
@当您声明一个接受多个参数的函数时,Yakk解决方案似乎更好。
例如,如果一个函数使用两个int l/r值引用参数,并使用模板返回int引用,则会导致混乱的签名。
template<typename T1, typename T2>
int& foo(T1 &&a, T2 &&b) {
a += b;
return a;
}
而@Yakk解决方案提供了一个非常优雅的解决方案。
int& foo(any_ref<int> a, any_ref<int> b) {
a += b;
return a;
}
template<class T>
struct any_ref{
T& t;
any_ref(T&in):t(in){}
any_ref(T&&in):any_ref(in){}
any_ref(any_ref const&)=default;
any_ref& operator=(any_ref const&)=default;
~any_ref()=default;
operator T&()const&{return t;}
operator T&&()&&{return std::move(t);}// maybe
T& get()const{return *this;}
};
然后:
void foo(any_ref<int>a, any_ref<int>b);
不是模板函数。如果实体想要真正的引用,它可以执行int&a=a_arg;
。
但实际上,如果您想要一个"可能out"参数,只需使用int&
即可。想要将右值作为左值传递的调用者可以写:
templare<class T>
T& as_lvalue(T&&t){return t;}
并抛弃他们的富足。
如果参数是只读引用,请使用const&
。
相关文章:
- 区分接受常量参数的函数引用/指针和与函数参数同名的非常量参数
- 类 Referention 中C++回调函数引用非静态函数
- 使用函数引用指向节点的指针删除链表中的节点?
- 解释通过从函数引用返回数组的语法
- "Class1"类"Class2"对象作为私有数据成员。如何通过"Class 2"函数引用"Class1"对象?
- 使用默认构造函数引用成员变量初始化错误
- 无法调用函数引用 c++
- 使用 decltype(this) 获取函数引用
- 我应该如何定义返回指针的函数?(引用指针与指针指针)
- 从内联函数引用文件静态变量
- Boost::将sigaction函数引用绑定到实例
- 一种比函数引用更有效的方法
- 奇怪的未定义函数引用,函数调用C++不存在
- 是否可以检测绑定成员函数引用的对象是否被删除或销毁
- 构造函数引用参数导致seg错误
- 是否可以使函数模板从函数引用中获取“decltype”
- 无法让 Lua 函数引用"self"
- 如何解析变量和函数引用(Linker & Compiler)?
- 从不同模块调用函数 - 引用错误
- 如何在主函数中连接到数据库,然后从其他函数引用它