? ? ? ?一般情況下不要使用std::endl,尤其是在循環中,因為可能一開始你只是想要打印一個換行符,但是"endl"做的更多,其還會刷新緩沖區,這會額外花費很多時間,相反,只需要使用“\n",就可以做的更好,例如下面這個程序例子。
#include <iostream>void print_Number(int start,int end)
{for(auto i=start;i!=end;i++){std::cout<<i<<"\n";}
}int main()
{print_Number(10,15);
}
? ? ? 當基于范圍的for循環能更好的表達意圖的時候,卻使用索引的for循環
#include <iostream>
#include <vector>void know_your_algorithms()
{const std::vector<int> data={-1,-3,-5,8,15,-1};std::size_t first_pos_idx;for(std::size_t i=0;i<data.size();i++){if(data[i]>0){first_pos_idx=i;break;}}std::cout<<data[first_pos_idx]<<"\n";
}
int main()
{know_your_algorithms();
}
但是在這里我們可以尋找是否已經有算法可以滿足我們需要做到的事情,例如下面的例子
#include <iostream>
#include <vector>
#include <algorithm>void know_your_algorithms()
{const std::vector<int> data={-1,-3,-5,8,15,-1};const auto is_positive=[] (const auto &x){return x>0;};auto first_pos_it=std::find_if(data.begin(),data.end(),is_positive);if(first_pos_it!=data.end()){std::cout<<*first_pos_it<<"\n";}
}
int main()
{know_your_algorithms();
}
其中這里的
const auto is_positive=[](const auto &x) {return x>0;};
是C++語言中的lambda表達式,其解釋為:
const auto is_positive = [](const auto& x) { return x > 0; };
// ▲ ▲ ▲ ▲ ▲ ▲
// | | | | | |
// 常量 自動類型 Lambda 參數類型 參數 函數體
// | 推導 起始符 推導 引用
[](const auto& x) { return x > 0; }
?Lambda表達式簡介
[捕獲變量] (參數列表) 可選限定符->返回類型{//函數代碼
}
#include <iostream>int main()
{int x=7;float y=3.0;auto p=[x,y] (int a,int b)->float{return x*y+a*b;};std::cout<<p(10,20)<<"\n";
}
下面我們直接將lambda表達式作為實際參數傳入
#include <iostream>
#include <vector>
#include <algorithm>int main()
{std::vector<float> numbers{1.1,2.0,3.5,-1.4,29.2,12.1,33,6,0};sort(numbers.begin(),numbers.end(),[](float a,float b){return a<b;});for(auto v:numbers) std::cout<<v<<" ";
}
lambda表達式實際上是函數對象的一種快捷定義方式,如果我們用結構體來表示,其為:
#include <iostream>
#include <vector>
#include <algorithm>int main()
{int x=7;float y=3.0;struct{int x;float y;float operator()(int a,int b)const{return x*y+a*b;}}p{x,y};std::cout<<p(10,20);
}
在這里,我們雖然改變了y的值,但是這兩個函數的輸出是一模一樣的?
#include <iostream>
#include <vector>
#include <algorithm>int main()
{int x=7;double y=2.3;auto p=[x,y](int a,int b)->float{return x*y+a*b;};std::cout<<p(10,20)<<"\n";y+=1.5;std::cout<<p(10,20)<<"\n";}
原因就是因為lambda函數對象中的對應成員變量只是在初始化時復制了y的值,所以再次使用同樣的參數調用函數對象時,結果不會發生變化,但是如果我們在引用的前面加上引用運算符&,則表示其為按引用捕獲
#include <iostream>
#include <vector>
#include <algorithm>int main()
{int x=7;double y=2.3;auto p=[&x,&y](int a,int b)->float{return x*y+a*b;};std::cout<<p(10,20)<<"\n";y+=1.5;std::cout<<p(10,20)<<"\n";}
因此其輸出的結果為下面
另外,lambda所對應的函數調用運算符默認是const函數,也就是說,函數內部不能修改按值捕獲的成員變量,但是可以通過加上mutable修飾符,這樣捕獲的成員函數都是可以修改的了。
默認捕獲方式?
//默認按值捕獲
[=]
//默認按引用捕獲
[&]
#include <iostream>int main()
{int x=7;float y=3.0;float z=-1;auto p=[&](int a,int b)->float{return x*y*z+a*b;};y+=2;std::cout<<p(10,20)<<"\n";
}
這個就是按引用捕獲,因此其y發生變化的時候,下面的輸出會有變化。
#include <iostream>int main()
{int x=7;float y=3.0;float z=-1;auto p=[=,&y](int a,int b)->float{return x*y*z+a*b;};y+=2;std::cout<<p(10,20)<<"\n";
}
?