網(wǎng)站建設(shè)需要什么專業(yè)如何推廣平臺(tái)
3.1 重新定義的auto關(guān)鍵字
1.當(dāng)用一個(gè)auto關(guān)鍵字聲明多個(gè)變量的時(shí)候,編譯器遵從由左往右的推導(dǎo)規(guī)則,以最左邊的表達(dá)式推斷auto的具體類型
int n = 5;
auto *pn = &n, m = 10;// 這里auto被推導(dǎo)為 int 所以int m = 10;合理
auto *pns = &n, m = 10.0;//編譯失敗,聲明類型不統(tǒng)一
2.當(dāng)使用條件表達(dá)式初始化auto聲明的變量時(shí),編譯器總是使用表達(dá)能力更強(qiáng)的類型:
auto i = true ? 5 : 8.0; // i的數(shù)據(jù)類型為double
3.雖然C++11標(biāo)準(zhǔn)已經(jīng)支持在聲明成員變量時(shí)初始化(見(jiàn)第8章),但是auto卻無(wú)法在這種情況下聲明非靜態(tài)成員變量
struct sometype {
auto i = 5; // 錯(cuò)誤,無(wú)法編譯通過(guò)
}struct sometype {
static const auto i = 5;
};//這個(gè)樣子可以 但是i就是常量了 C++17修改
struct sometype {
static inline auto i = 5;
};
4.按照C++20之前的標(biāo)準(zhǔn),無(wú)法在函數(shù)形參列表中使用auto聲明形參(注意,在C++14中,auto可以為lambda表達(dá)式聲明形參):
3.2 推導(dǎo)規(guī)則
1.在進(jìn)行值傳遞的時(shí)候忽略原始的CV限定
const int i = 5; auto j = i; // auto推導(dǎo)類型為int,而非const int auto &m = i; // auto推導(dǎo)類型為const int,m推導(dǎo)類型為const int& auto *k = i; // auto推導(dǎo)類型為const int,k推導(dǎo)類型為const int* const auto n = j; // auto推導(dǎo)類型為int,n的類型為const int
2.使用auto聲明變量初始化時(shí),目標(biāo)對(duì)象如果是引用,則引用屬性會(huì)被忽略:
int i = 5; int &j = i; auto m = j; // auto推導(dǎo)類型為int,而非int&
3.使用auto和萬(wàn)能引用聲明變量時(shí)(見(jiàn)第6章),對(duì)于左值會(huì)將auto推導(dǎo)為引用類型
int i = 5; auto&& m = i; // auto推導(dǎo)類型為int& (這里涉及引用折疊的概念) auto&& j = 5; // auto推導(dǎo)類型為int
根據(jù)規(guī)則3,因?yàn)閕是一個(gè)左值,所以m的類型被推導(dǎo)為int&, auto被推導(dǎo)為int&,這其中用到了引用折疊的規(guī)則。而5是一個(gè)右值,因此j的類型被推導(dǎo)為int&&,auto被推導(dǎo)為int。
?
4.使用auto聲明變量,如果目標(biāo)對(duì)象是一個(gè)數(shù)組或者函數(shù),則auto會(huì)被推導(dǎo)為對(duì)應(yīng)的指針類型:
?int i[5]; auto m = i; // auto推導(dǎo)類型為int* int sum(int a1, int a2) {return a1+a2; } auto j = sum // auto推導(dǎo)類型為int (__cdecl *)(int,int)
思考?
class Base {
public:virtual void f(){std::cout << "Base::f()" << std::endl;};
};
class Derived : public Base {
public:virtual void f() override{std::cout << "Derived::f()" << std::endl;};
};Base* d = new Derived();auto& b = *d;//auto b = *d; b.f();
auto b? 調(diào)用基類函數(shù)? auto& b調(diào)用子類的函數(shù)
個(gè)人認(rèn)為的解釋:*d的類型是確定的Base? auto b = *d; 那邊auto就是推導(dǎo)出來(lái)的Base 所以調(diào)用的就是Base的f函數(shù)
而 auto&b? 編譯器推導(dǎo)出變量的類型時(shí),會(huì)保留右值表達(dá)式的引用性?
右值 *d 的類型是 Base&,即 d 指向的 Derived 對(duì)象被解引用為 Base& 類型。
因此,b 的類型推導(dǎo)為 Base&(對(duì) Base 的引用),實(shí)際引用的是 Derived 對(duì)象。所以會(huì)調(diào)用Derived的f函數(shù)
3.3 什么時(shí)候使用auto
?
1.當(dāng)一眼能看出類型的時(shí)候使用auto
一般是在遍歷容器的時(shí)候使用?
如
vector<int> x{ 1,2,3 };for (vector<int>::iterator it = x.begin(); it != x.end(); ++it){}//等價(jià)于for (auto = x.begin(); it != x.end(); ++it){}//當(dāng)使用map的時(shí)候 對(duì)于這個(gè)容器遍歷前面的 string應(yīng)該為coonststd::map<std::string, int> str2int;//這個(gè)可以不加constfor (map< std::string, int>::iterator it = str2int.begin(); it != str2int.end(); ++it){cout << it->second << endl;}//這個(gè)得加for (pair<const string,int> &it : str2int){cout << it.second << endl;}
2.用于lambda 與bind?
auto l = [](int a1, int a2) { return a1 + a2; };
int sum(int a1, int a2) { return a1 + a2; };auto b = std::bind(sum, 5, std::placeholders::_1);
?
3.4 返回類型推導(dǎo)
?
C++14標(biāo)準(zhǔn)支持對(duì)返回類型聲明為auto的推導(dǎo)
?auto sum(int a1, int a2) { return a1 + a2; };
如果有多個(gè)返回值 要返回值的類型一致
不同的返回類型會(huì)導(dǎo)致編譯失敗。
3.5lambda表達(dá)式中使用auto類型推導(dǎo)
在C++14標(biāo)準(zhǔn)中我們還可以把a(bǔ)uto寫到lambda表達(dá)式的形參中,這樣就得到了一個(gè)泛型的lambda表達(dá)式
?auto l = [](auto a1, auto a2) { return a1 + a2; }; auto retval = l(5, 5.0); //在上面的代碼中a1被推導(dǎo)為int類型,a2被推導(dǎo)為double類型,返回值retval被推導(dǎo)為double類型。
返回auto引用的方法
auto l = [](int &i)->auto& { return i; }; auto x1 = 5; auto &x2 = l(x1); assert(&x1 == &x2); // 有相同的內(nèi)存地址
3.6 非類型模板形參占位符
?
c++17引入?它可以作為非類型模板形參的占位符
#include <iostream> template<auto N> void f() {std::cout << N << std::endl; } int main() {f<5>(); // N為int類型f<'c'>(); // N為char類型f<5.0>(); // 編譯失敗,模板參數(shù)不能為double }
c++17才有?