15. extern template
避免多重實例化模版,明確指定模版於它處
實例化
編譯器毋需重複實例化,待鏈結時期再尋找
實例化後的程式碼即可
#include "MyVector.h"
extern template class MyVector<int>; // Suppresses implicit instantiation below --
// MyVector<int> will be explicitly instantiated elsewhere
void foo(MyVector<int>& v)
{
// use the vector in here
}
-------------------------------------------
#include "MyVector.h"
template class MyVector<int>; // Make MyVector available to clients (e.g., of the shared library
*http://www.stroustrup.com/C++11FAQ.html#extern-templates
*http://zevoid.blogspot.tw/2012/04/c11-extern-template.html
17. enum class(更高階的enum)
Scoped and Strongly typed enums
VC10中並未支援,VC11已支援
enum Alert { green, yellow, election, red };
enum class Color { red, blue };
enum class TrafficLight { red, yellow, green };
Alert a = 7;
Color c = 7;
int a2 = red;
int a3 = Alert::red;
int a4 = blue;
int a5 = Color::blue;
Color a6 = Color::blue;
Error Error in C++98; OK in C++11
18. 指定enum的底層型別
並同時決定enum的佔用空間
在過去,佔用空間取決於實作而定
底層型別必須是整數型的型別,預設為int
enum class Color : char { red, blue };
enum class TrafficLight { red, yellow, green };
enum E { E1 = 1, E2 = 2, Ebig = 0xFFFFFFF0U }; // how big is an E?
enum EE : unsigned long { EE1 = 1, EE2 = 2, EEbig = 0xFFFFFFF0U };
19. enum的先行宣告
C++11中可以做先行宣告了
enum class Color_code : char;
void foobar(Color_code* p);
// ...
enum class Color_code : char { red, yellow, green, blue };
21. 對POD定義的修改
POD(Plain Old Data)
符合這種定義的型別能夠允許產生與C相容
的物件佈局
在C++98,POD指的是像C中struct那樣的資
料
能使用memcpy()
能使用memset()進行初始化
struct S { int a; }; // S is a POD
struct SS { int a; SS(int aa) : a(aa) { } }; // SS is not a POD
struct SSS { virtual void f(); /* ... */ };
22. C++11中的POD
struct S { int a; }; // S is a POD
struct SS { int a; SS(int aa) : a(aa) { } }; // SS is a POD
struct SSS { virtual void f(); /* ... */ };
在C++11中,SS也是個POD
建構式並不影響
SSS 不會是POD,因為會有個虛擬函式表
C++定義POD是可複製的型別、極簡型別、
以及具有標準佈局的型別
VC10中並未支援,VC11已支援
26. 區域及不具名的型別做為模版的參數
在C++98,區域及不具名的型別不能做為模
版的參數傳入
如今,在C++11中支援了
一致性更好
void f(vector<X>& v)
{
struct Less {
bool operator()(const X& a, const X& b)
{ return a.v<b.v; }
};
sort(v.begin(), v.end(), Less()); // C++98: error: Less is local
// C++11: ok
}
*http://www.stroustrup.com/C++11FAQ.html#local-types
27. 不具名型別的值也能做為模版參數
template<typename T> void foo(T const& t){}
enum X { x };
enum { y };
int main()
{
foo(x); // C++98: ok; C++11: ok
foo(y); // C++98: error; C++11: ok
enum Z { z };
foo(z); // C++98: error; C++11: ok
}
28. auto Keyword (1/3)
auto 關鍵字能從所宣告變數的初始算式,導
出其型別 ( 當然是編譯時期 )
auto declarator initializer;
int j = 0;
auto k = 0; // Variable k is implicitly type int
*http://msdn.microsoft.com/en-us/library/dd293667(v=VS.100).aspx
29. auto Keyword (2/3)
map<int,list<string>>::iterator i = m.begin();
auto i = m.begin();
auto x = 1, *y = &x, **z = &y; // Resolves to int.
auto a(2.01), *b (&a); // Resolves to double.
auto c = 'a', *d(&c); // Resolves to char.
auto m = 1, &n = m; // Resolves to int.
30. auto Keyword (3/3)
使用 auto 關鍵字時的重要限制
使用時一定要搭配 initializer
不能用來宣告陣列、變數的 return type、函
式或 template 的參數
除了 static member 之外,不能在
class/struct 中使用 auto 宣告 data member
31. 錯誤的 auto 使用
auto a;
auto ary[10];
auto ary2[] = { 1, 2, 3}
auto foo();
void bar(auto a);
struct A
{
auto a;
};
33. auto vs. auto
/Zc:auto[-] 編譯器選項是用來告訴編譯器看
待宣告變數時 auto 這個關鍵字的確切意義
指定 /Zc:auto 編譯器會從所宣告變數的初始
算式推導出其確型別
指定 /Zc:auto- 編譯器會以 automatic
storage class 來宣告變數
此為相容性問題
*http://msdn.microsoft.com/en-us/library/dd293615.aspx
34. decltype Type Specifier (1/2)
decltype 是個 type specifier
decltype 依據所給定的算式來決定型別
decltype( expression )
decltype 不同於 typeid,因為它是從算式中
得到型別本身,而非型別資訊
35. decltype Type Specifier (2/2)
int var;
const int&& fx();
struct A { double x; }
const A* a = new A();
decltype(fx()); // const int &&
decltype(var) // int
decltype(a->x) // double ( The type of the member
access )
decltype((a->x)) // const double && (an expression
instead of a member access )
39. Ranged-for
透過Ranged-for 述句,可以在迴圈裡遞代一
組元素
所有標準的容器、 std::string 、初始化列表
、陣列、以及所有可以定義begin()及end()的
類別都可適用
void f(vector<double>& v)
{
for (auto x : v) cout << x << 'n';
for (auto& x : v) ++x;
}
for (const auto x : { 1,2,3,5,8,13,21,34 }) cout << x << 'n';
*http://www.stroustrup.com/C++11FAQ.html#aims
44. Lambda Expressions (4/4)
parameter list
不能有預設引數
不能有可變長度引數列表
不能有不具名參數
沒有參數時,可省略 parameter list
int main()
{
int x = 4;
int y = 5;
int z = [=] { return x + y; } ;
}
83. array_view<T, N>
vector<int> v(10);
檢視CPU或GPU
上既存的資料
extent<2> e(2,5);
元素型別T,並有 array_view<int,2> a(e, v);
N維
需指定extent
矩形
//above two lines can also be written
隨處可存取(自動
//array_view<int,2> a(2,5,v);
同步)
index<2> i(1,3);
int o = a[i]; // or a[i] = 16;
//or int o = a(1, 3);