1. 程式人生 > 其它 >模板實參推斷與bind,ref總結

模板實參推斷與bind,ref總結

模板實參推斷與bind,ref總結

template <typename T> func(T arg)

  1. 模板形參沒有任何引用,會忽略頂層const,比如傳入const int,則T的引數仍為int
  2. 不會忽略底層const,比如傳入const int* const,則T的引數為const int*
  3. 忽略引用

template <typename T> func(T& arg)

  1. 並不忽略頂層const,若傳入const int&,則T為const int
  2. 若傳入引用,將T推斷為remove_reference
  3. 僅接受左值

template <typename T> func(const T& arg)

  1. 相比上者可傳入右值,比如func(5),則T的型別為int

template <typename T> func(T&& arg)

  1. 俗稱萬能引用,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傳入引數也是這樣的道理