預(yù)定義宏
1. func預(yù)定義標(biāo)識符
功能:返回所在函數(shù)的名字
C++11中甚至允許在類或結(jié)構(gòu)體中使用:
#include<iostream>
using namespace std;
class TestStruct {
public:
TestStruct () : name(__func__) {}
const char *name;
};
int main() {
TestStruct ts;
cout << ts.name <<endl;
}
原理:編譯器隱式地在函數(shù)定義后定義func表示符
所以需要注意的是func不能作為函數(shù)參數(shù)的默認(rèn)值泰偿,因?yàn)樵趨?shù)聲明的時(shí)候敞峭,func還沒有被定義
void testFun(string func_name = __func__) {}; //compile error
2.宏__cplusplus
C++11的__cplusplus被預(yù)定義為201103L靖苇,可以用
#ifdef __cplusplus < 201103L
#error "please use C++11 implementation"
#endif
進(jìn)行檢測
靜態(tài)斷言
assert函數(shù)是在運(yùn)行時(shí)進(jìn)行斷言球涛,而當(dāng)需要在編譯時(shí)斷言則需要使用靜態(tài)斷言,在C++11中辕坝,引入了static_assert拆座,接受兩個(gè)參數(shù)匪傍,static_assert ( bool_constexpr , message )
一個(gè)是斷言表達(dá)式(通常返回bool值)材彪,一個(gè)是警告信息
當(dāng)然观挎,利用“不能除以0”的性質(zhì)也可以實(shí)現(xiàn)靜態(tài)斷言,但效果明顯沒有C++11標(biāo)準(zhǔn)中的好(畢竟標(biāo)準(zhǔn)直接報(bào)錯(cuò)警告信息段化,而這樣實(shí)現(xiàn)只會報(bào)不能/0嘁捷,這樣還會增加調(diào)試難度)
#include<iostream>
#include<cstring>
using namespace std;
#define assert_static(e) \
do{ \
enum{ assert_static__ = 1/ (e) }; \
}while (0)
template <typename T, typename U> int bit_copy(T&a, U& b){
assert_static(sizeof(b) == sizeof(a));
}
int main(){
int a = 1;
double b = 3;
bit_copy(a,b);
}
noexcept修飾符與noexcept操作符
noexcept比throw()在效率上會高一些,在 C++11中显熏,noexcept替代了throw()
noexcept修飾符
noexcept修飾符有兩種形式雄嚣,一種是直接加上關(guān)鍵字noexcept,而另外一種則可以接受一個(gè)常量表達(dá)式作為參數(shù)
void excpt_func() noexcept (常量表達(dá)式);
量表達(dá)式的結(jié)果會被轉(zhuǎn)換成一個(gè)bool類型的值喘蟆。該值為true缓升,表示函數(shù)不會拋出異常,反之蕴轨,則有可能拋出異常港谊。這里,不帶常量表達(dá)式的noexcept相當(dāng)于聲明了noexcept(true)尺棋,即不會拋出異常封锉。
在通常情況下,在C++11中使用noexcept可以有效地阻止異常的傳播與擴(kuò)散膘螟。
noexcept操作符
noexcept作為一個(gè)操作符時(shí)成福,通常可以用于模板荆残。
我的測試代碼:
#include<iostream>
#include<cstring>
using namespace std;
class Test{
public:
Test() {
throw 1;
cout<<"constructor"<<endl;
}
~Test() {
cout<<"dtor"<<endl;
}
};
template <class T>
void fun() noexcept(noexcept(T())) {
throw 1;
}
int main(){
try{
fun<Test>();
}
catch(...){
cout<<"caught"<<endl; //caught
}
try{
fun<int>();
}
catch(...){
cout<<"caught"<<endl; //terminate called after throwing an instance of 'int'
}
return 0;
}
noexcept(noexcept(T()))中奴艾,第二個(gè)noexcept就是一個(gè)noexcept操作符。當(dāng)其參數(shù)是一個(gè)有可能拋出異常的表達(dá)式的時(shí)候内斯,其返回值為false蕴潦,反之為true(實(shí)際noexcept參數(shù)返回false還包括一些情況,這里就不展開講了)俘闯。
對于測試代碼中的例子潭苞,當(dāng)模板實(shí)參為Test時(shí),Test()可能拋出異常真朗,所以這時(shí)候此時(shí)簽名修飾符為noexcept(false)此疹,所以可以拋出異常
而當(dāng)模板實(shí)參為int的時(shí)候,noexcept(noexcept(T()))為noexcept(true)遮婶,所以這時(shí)候試圖拋出異常的話蝗碎,會直接調(diào)用std::terminate終端程序的執(zhí)行
另外需要注意的是,析構(gòu)函數(shù)默認(rèn)為noexcept旗扑,delete函數(shù)默認(rèn)為noexcept
快速初始化成員變量
C++11增加允許了使用=或者花括號{}的方式來初始化:
struct init{ int a = 1; double b {1.2}; };
這樣的方式也叫就地初始化蹦骑,然而有一個(gè)問題,這樣的初始化方式與初始化列表是否沖突臀防?
當(dāng)然不會沖突:
class Test{
public:
Test(string ss = "234"):s(ss){}
string s {"123"};
};