網(wǎng)站建設(shè)需要什么專業(yè)如何推廣平臺
3.1 重新定義的auto關(guān)鍵字
1.當用一個auto關(guān)鍵字聲明多個變量的時候,編譯器遵從由左往右的推導(dǎo)規(guī)則,以最左邊的表達式推斷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.當使用條件表達式初始化auto聲明的變量時,編譯器總是使用表達能力更強的類型:
auto i = true ? 5 : 8.0; // i的數(shù)據(jù)類型為double
3.雖然C++11標準已經(jīng)支持在聲明成員變量時初始化(見第8章),但是auto卻無法在這種情況下聲明非靜態(tài)成員變量
struct sometype {
auto i = 5; // 錯誤,無法編譯通過
}struct sometype {
static const auto i = 5;
};//這個樣子可以 但是i就是常量了 C++17修改
struct sometype {
static inline auto i = 5;
};
4.按照C++20之前的標準,無法在函數(shù)形參列表中使用auto聲明形參(注意,在C++14中,auto可以為lambda表達式聲明形參):
3.2 推導(dǎo)規(guī)則
1.在進行值傳遞的時候忽略原始的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聲明變量初始化時,目標對象如果是引用,則引用屬性會被忽略:
int i = 5; int &j = i; auto m = j; // auto推導(dǎo)類型為int,而非int&
3.使用auto和萬能引用聲明變量時(見第6章),對于左值會將auto推導(dǎo)為引用類型
int i = 5; auto&& m = i; // auto推導(dǎo)類型為int& (這里涉及引用折疊的概念) auto&& j = 5; // auto推導(dǎo)類型為int
根據(jù)規(guī)則3,因為i是一個左值,所以m的類型被推導(dǎo)為int&, auto被推導(dǎo)為int&,這其中用到了引用折疊的規(guī)則。而5是一個右值,因此j的類型被推導(dǎo)為int&&,auto被推導(dǎo)為int。
?
4.使用auto聲明變量,如果目標對象是一個數(shù)組或者函數(shù),則auto會被推導(dǎo)為對應(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ù)
個人認為的解釋:*d的類型是確定的Base? auto b = *d; 那邊auto就是推導(dǎo)出來的Base 所以調(diào)用的就是Base的f函數(shù)
而 auto&b? 編譯器推導(dǎo)出變量的類型時,會保留右值表達式的引用性?
右值 *d 的類型是 Base&,即 d 指向的 Derived 對象被解引用為 Base& 類型。
因此,b 的類型推導(dǎo)為 Base&(對 Base 的引用),實際引用的是 Derived 對象。所以會調(diào)用Derived的f函數(shù)
3.3 什么時候使用auto
?
1.當一眼能看出類型的時候使用auto
一般是在遍歷容器的時候使用?
如
vector<int> x{ 1,2,3 };for (vector<int>::iterator it = x.begin(); it != x.end(); ++it){}//等價于for (auto = x.begin(); it != x.end(); ++it){}//當使用map的時候 對于這個容器遍歷前面的 string應(yīng)該為coonststd::map<std::string, int> str2int;//這個可以不加constfor (map< std::string, int>::iterator it = str2int.begin(); it != str2int.end(); ++it){cout << it->second << endl;}//這個得加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標準支持對返回類型聲明為auto的推導(dǎo)
?auto sum(int a1, int a2) { return a1 + a2; };
如果有多個返回值 要返回值的類型一致
不同的返回類型會導(dǎo)致編譯失敗。
3.5lambda表達式中使用auto類型推導(dǎo)
在C++14標準中我們還可以把auto寫到lambda表達式的形參中,這樣就得到了一個泛型的lambda表達式
?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才有?