C++备忘录058:Template Type Deduction gist "Effective Modern C++"
程序员文章站
2024-02-29 08:59:40
...
Template Type Deduction
template<typename T> void f(ParamType param);
f(expr);
Case 1: ParamType
is a Reference or Pointer, but not a Universal Reference
- if
expr
's type is a reference, ignore the refernece part - Then pattern-matched
expr
's type againstParamType
to determineT
.
template <typename T> void f(T& param);
int x = 27;
f(x); // T is int, param's type is int&
int const cx = x;
f(cx); // T is int const, param's type is int const&
int const& rx = x;
f(rx); // T is int const, param's type is int const&
template <typename T> void f(T const& param);
int x = 27;
f(x); // T is int, param's type is int const&
int const cx = x;
f(cx); // T is int, param's type is int const&
int const& rx = x;
f(rx); // T is int, param's type is int const&
template <typename T> void f(T* param);
int x = 27;
f(&x); // T is int, params type is int*
int const* px = &x;
f(px); // T is int const, params type is int const*
Case 2: ParamType
is a Universal Reference
- If
expr
is an lvalue, bothT
andParamType
are deduced to be lvalue references. That’s doubly unusual.- It’s the only situation in template type deduction where
T
is deduced to be a reference. - Although
ParamType
is declared using the syntax for an ravlue reference, its deduced type is an lvalue reference.
- It’s the only situation in template type deduction where
- If
expr
is an rvalue, the “normal” (i.e., Case 1) rule apply
template <typename T> void f(T&& param);
int x = 27;
f(x); // T is int&, param's type is int&
int const cx = x;
f(cx); // T is int const&, param's type is int const&
int const& rx = x;
f(rx); // T is int const&, param's type is int const&
f(27); // T is int, param's type is int&&
Case 3: ParamType
is Neither a Pointer nor a Reference
- As before, if
expr
's type is a reference, ignore the reference part. - If, after ignoring
expr
's refernece-neww,expr
isconst
/volatile
, ignore that.
template <typename T> void f(T param);
int x = 27;
f(x); // T is int, param's type is int
int const cx = x;
f(cx); // T is int, param's type is int
int const& rx = x;
f(rx); // T is int, param's type is int
auto
Type Deduction
When a variable is declared using auto
, auto
plays the role of T in the template, and the type specifier for the variable acts as Paramtype
.
auto&& uref1 = x; // x is int and lvalue, so uref1's type is int&
auto&& uref2 = cx; // cx is int const and lvalue, so uref2's type is int const&
auto&& uref3 = 27; // 27 is int and rvalue, so uref3's type is int&&
auto x = 27; // x is int
template <typename T> void func_for_x(T param);
func_for_x(27);
auto const cx = x; // cx is int const
template <typename T> void func_for_cx(T const param);
func_for_cx(x);
auto const& rx = x; // rx is int const&
template <typename T> void func_for_rx(T const& param);
func_for_rx(x);
推荐阅读
-
C++备忘录058:Template Type Deduction gist "Effective Modern C++"
-
C++备忘录062:Corner Cases for std::move/std::forward gist of "Effective Modern C++"
-
C++备忘录063:Overloading on Universal References gist of "Effective Modern C++"
-
C++备忘录060:noexcept gist of "Effective Modern C++"
-
C++备忘录061:smart pointers gist of "Effective Modern C++"