auto — 自动推导
auto i = 42 ; // int
auto d = 3.14 ; // double
auto s = "hello" s ; // std::string
auto v = vector { 1 , 2 , 3 }; // vector<int>
// ⚠️ auto 会丢掉引用和顶层 const
const int & cr = i ;
auto x = cr ; // int(丢掉了 const 和 &)
auto & y = cr ; // const int &(保留引用,const 也随之保留)
// 保持 const
const auto z = cr ; // const int
// C++14: auto 函数返回
auto sum ( int a , int b ) { return a + b ; }
// C++20: auto 函数参数(简写模板)
// void foo(auto x) { } 等价于 template<typename T> void foo(T x) { }
auto 推导规则 = 模板推导规则
template < typename T >
void foo ( T param ); // 传值 → 丢掉 const、引用、volatile
template < typename T >
void bar ( T & param ); // 传引用 → 保留 const,T 推导为 const 类型
decltype — 获取声明类型
int x = 42 ;
decltype ( x ) y = 10 ; // int
const int & cr = x ;
decltype ( cr ) z = x ; // const int &(原封不动保留)
// decltype(表达式) — 表达式的值类别影响结果
decltype ( x ) a = x ; // int(x 是变量名)
decltype (( x )) b = x ; // int &((x) 是左值表达式!)
// 函数返回值
int foo ();
decltype ( foo ()) result = foo (); // int
// 推导成员类型
vector < int > v ;
decltype ( v ) ::value_type val ; // int
decltype ( v . begin ()) it ; // vector<int>::iterator
decltype(auto) — C++14 的精确转发
// 场景:想完美转发函数的返回值类型
int & getRef ();
int getVal ();
// ❌ auto 丢掉引用
auto r1 = getRef (); // int
// ❌ decltype 需要重复表达式
decltype ( getRef ()) r2 = getRef (); // int &,但写了两遍
// ✅ decltype(auto) — 精确推导,不丢引用
decltype ( auto ) r3 = getRef (); // int &
decltype ( auto ) r4 = getVal (); // int
实用:完美转发函数返回值
template < typename F , typename ... Args >
decltype ( auto ) invoke ( F && f , Args && ...args ) {
return forward < F >( f )( forward < Args >( args ) ... );
}
尾置返回类型
// 需要 decltype 参数 → 参数在返回类型后面
template < typename T , typename U >
auto multiply ( T && a , U && b ) -> decltype ( a * b ) {
return a * b ;
}
// C++14 简化
template < typename T , typename U >
decltype ( auto ) multiply ( T && a , U && b ) {
return a * b ;
}
// 实际场景:lambda 中
auto cmp = []( const auto & a , const auto & b ) -> decltype(a < b) {
return a < b ;
};
实际应用
// 1. 范围 for
for ( const auto & item : container ) { } // 避免拷贝
for ( auto && item : container ) { } // 万能引用
// 2. 结构化绑定(C++17)
map < string , int > m ;
for ( auto && [ key , value ] : m ) { } // key=const string&, value=int&
auto [ it , inserted ] = m . insert ( { "x" , 1 } );
// it = map::iterator, inserted = bool
// 3. 简化迭代器
auto it = v . begin (); // 替代 vector<int>::iterator
// 4. 通用 Lambda(C++14)
auto genericLambda = []( const auto & x , const auto & y ) {
return x + y ;
};
速查表
写法 行为 保留引用 保留 const auto值语义推导 ❌ ❌ auto &左值引用 ✅ ✅ const auto &const 左值引用 ✅ ✅ auto &&万能引用 取决于初始化值 取决于初始化值 decltype(expr)精确推导表达式类型 ✅ ✅ decltype(var)精确推导变量声明类型 ✅ ✅ decltype((var))总是左值引用 ✅ ✅ decltype(auto)同 decltype,但免写表达式 ✅ ✅
不要过度使用
// ❌ — 类型信息丢失,可读性下降
auto result = someFunction ();
// result 是什么?得跳转到 someFunction 才知道
// ✅ — 类型明确或无关紧要时用 auto
auto it = map . find ( key );
for ( const auto & x : vec ) ...