c/c++ 模板 型別推斷

小石王發表於2019-01-24

模板型別的推斷

下面的函式f是個模板函式,typename T。下表是,根據呼叫測的實參,推斷出來的T的型別。

請注意下表的紅字部分, f(T&& t)看起來是右值引用,但其實它會根據實參的型別,來決定T的型別,如果實參是左值,則它是左值,如果實參是右值,則它是右值。

所以可以看出來,T&可以變成const& ,f(T&& t)也可以變成const&。

f(T t) f(const T t)   f(T& t) f(const T& t) f(T&& t) f(const T&& t)
f(1) f<int> f<int> error cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int` f<int> f<int> f<int>
int i = 1;
f(i);
f<int> f<int>   f<int> f<int> f<int&> error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘int’
int& ri = i;
f(ri);
f<int> f<int>    f<int> f<int> f<int&> cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘int’
const int ci = 2;
f(ci);
f<int> f<int>    f<const int> f<int> f<const int&> cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘const int’
const int& rci = ci;
f(rci);
f<int> f<int>    f<const int> f<int> f<const int&> cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘const int’

實驗程式碼

#include <iostream>

template<typename T>
void f1(T t){
  t = 99;
}

template<typename T>
void f4(const T t){
  //t = 99;
}

template<typename T>
void f2(T& t){
  //t = 99;
}

template<typename T>
void f3(const T& t){}


template<typename T>
void f5(T&& t){}

template<typename T>
void f6(const T&& t){}

int main(){
  /*
  //void f1(T t)
  f1(1);//int
  int i = 1;
  f1(i);//int
  int& ri = i;
  f1(ri);//int
  std::cout << ri << std::endl;
  const int ci = 2;
  f1(ci);//int
  const int& rci = ci;
  f1(rci);//int
  */

  /*
  //void f4(const T t)
  f4(1);//int
  int i = 1;
  f4(i);//int
  int& ri = i;
  f4(ri);//int
  std::cout << ri << std::endl;
  const int ci = 2;
  f4(ci);//int
  const int& rci = ci;
  f4(rci);//int
  */
  
  /*
  //void f2(T& t)
  //f2(1);//error cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
  int i = 1;
  f2(i);//int
  int& ri = i;
  f2(ri);//int
  const int ci = 2;
  f2(ci);//const int
  const int& rci = ci;
  f2(rci);//const int
  */

  /*
  //void f3(const T& t)
  f3(1);//int
  int i = 1;
  f3(i);//int
  int& ri = i;
  f3(ri);//int
  const int ci = 2;
  f3(ci);//int
  const int& rci = ci;
  f3(rci);//int
  */

  /*
  //void f5(T&& t)
  f5(1);//int
  int i = 1;
  f5(i);//int&
  int& ri = i;
  f5(ri);//int&
  std::cout << ri << std::endl;
  const int ci = 2;
  f5(ci);//const int&
  const int& rci = ci;
  f5(rci);//const int&
  */

  /*
  //void f6(const T&& t)
  f6(1);//int
  int i = 1;
  //f6(i);//error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘int’
  int& ri = i;
  //f6(ri);//error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘int’
  std::cout << ri << std::endl;
  const int ci = 2;
  //f6(ci);//error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘const int’
  const int& rci = ci;
  //f6(rci);//error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘const int’
  */
  
}

相關文章