模板实参推断与bind,ref总结
template <typename T> func(T arg)
- 模板形参没有任何引用,会忽略顶层const,比如传入const int,则T的参数仍为int
- 不会忽略底层const,比如传入const int* const,则T的参数为const int*
- 忽略引用
template <typename T> func(T& arg)
- 并不忽略顶层const,若传入const int&,则T为const int
- 若传入引用,将T推断为remove_reference
- 仅接受左值
template <typename T> func(const T& arg)
- 相比上者可传入右值,比如func(5),则T的类型为int
template <typename T> func(T&& arg)
- 俗称万能引用,T继承了arg原有的所有类型
bind与ref
先看一个代码片段
struct Sample
{
int a = 1;
void change(int &n)
{
n = 2;
}
function<void(void)> func = std::bind(&Sample::change, this, a);
};
template <typename T>
void g(T &&val)
{
}
int main(int argc, char **argv)
{
Sample s;
s.func();
cout<<a<<endl;
return 0;
}
结果不是2而是1,在cppreference中说到:The arguments to bind are copied or moved, and are never passed by reference unless wrapped in std::ref or std::cref.
如果std::bind(&Sample::change, this, std::ref(a))则会正常调用
查了下相关资料与reference_wrapper decay相关,暂时没有能力理解标准库代码。
注:往std::thread传入参数也是这样的道理