C++11:语法糖-自动类型推导auto与decltype

    科技2022-07-20  106

    C++11引入自动类型推导,首先在源代码中自动类型相当于占位符,编译器在编译阶段根据上下文关系推导出实际的类型,并根据实际的类型进行编译。

    auto:

    根据auto定义时,实际的右边类型进行编译。大大简化编程工作,并且由于编译期确定,不会带来运行期负担。

    int main() { map<string,int> mp; mp["str1"]=1; mp["str2"]=3; //传统遍历map方式 需要书写冗长的类型 for(map<string,int>::iterator it=mp.begin();it!=mp.end();it++) { cout<<it->first<<" "<<it->second<<endl; } cout<<"use auto"<<endl; //采取auto类型自动推导 for(auto it=mp.begin();it!=mp.end();it++) { cout<<it->first<<" "<<it->second<<endl; } }

    执行结果一致:

     

    auto类型推导在搭配增强for循环时,配合在容器类中使用,将更为简洁方便:

     

    int main() { map<string,int> mp; mp["str1"]=1; mp["str2"]=3; cout<<"use auto+for"<<endl; //采取auto类型+ 增强for 循环 for(auto it:mp) { cout<<it.first<<" "<<it.second<<endl; } }

    结果一致: 

     

    可用在返回值:

    auto fun(int i) { return i; } int main() { auto j=fun(1); cout<<j<<endl; }

    可用在类类型:

    class A { public: int val; }; int main() { A a; auto c=a; cout<<c.val<<endl; }

    用在函数参数?:

    C++11并未作规定,

    如果编译器能确定auto实际类型

    调用处语法通过,那么将可以通过编译。调用处语法不通过,那么无法通过编译。

    通过编译:

    auto fun(auto l) { l+=l; return l; } int main() { auto c=fun(10); cout<<c<<endl; }

    输出:

     

    编译不通过:

    auto fun(auto l) { l+=l; return l; } int main() { auto c=fun("12"); cout<<c<<endl; }

     

     

    由此可见:

    对于参数含有auto类型的,编译器会作警告,单独编译能够通过。但被其它部分调用处,编译可能不通过,取决于实际类型的语法。

    因此函数参数最好不要设置为auto类型。auto类型相当于编译器的语法糖,会在调用处展开为具体类型。

    语法糖:为了增加可读性与方便编程,编译器对语法糖作展开,与不使用语法糖编译后代码完全一致。

     

    decltype

    可以根据推导出的类型用于定义。

    推导出mp类型,并用此类型进行新的定义

    int main() { map<string,int> mp; decltype(mp) _mp; _mp["str"]=1; _mp["stc"]=2; }

     

    分析其与auto使用差别可以发现

    auto通常用于接受一个自动类型赋值。decltype则用于根据推导出的类型,进行新的定义。自动类型推导是编译期的语法糖,并不会带来运行期开销。

     

    Processed: 0.013, SQL: 8