c++11知識点の強化
初期化リスト(std::initializer_list) c++11はstd::initializer_を提供します.listは、クラスオブジェクトの初期化を通常の配列やPODデータと同様に初期化リストを使用することもできるようにします.クラスオブジェクトに初期化リストコンストラクション関数を指定すればよい. std::initializer_listは関数のパラメータとしても使用できます. 初期化リストstd::initializer_List関連サンプルコードは以下の通りです.
変長パラメータテンプレート(typename...Args) c++11は、黒魔法に匹敵する変長パラメータテンプレートを提供します.任意のタイプ、任意の数の変長パラメータテンプレートクラス、関数を実現できます. は、典型的な再帰テンプレート関数を用いて、変長パラメータテンプレート関数のパラメータを取り出すことができ、例示的なコードは以下の通りである. c++14は、初期化リストを使用して変長パラメータを展開できるより簡便な方法を提供し、サンプルコードは以下の通りである.
強いタイプ列挙(enum class) c++11は、タイプの安全な列挙クラスenum classを提供する.列挙クラスで定義された列挙値を暗黙的に整数に変換することはできず、整数と直接比較することもできず、異なる列挙タイプの列挙値と比較することもできない. 列挙クラス定義の列挙値は、同じ値を定義することができる. 列挙クラスでは、列挙値のタイプを自分で定義できます.デフォルトはintです. は、リロード<
は、テンプレート変換関数を定義して、列挙クラスの列挙値をintなどの基本データ型と直接比較することを容易にすることができる. のすべてのサンプルコードは以下のとおりです.
関数オブジェクトパッケージ(std::function) c++11は、任意の呼び出し可能なタイプを定義できる関数オブジェクトパッケージ(std::function)を提供し、これは関数オブジェクトのタイプに対する安全なパッケージである. std::functionとc++11が提供するより強力なusing構文とLambda関数を利用して、クラスオブジェクトの簡単なコールバック関数をより便利に実現することができます.サンプルコードは次のとおりです. コールバック関数が複雑でLambda関数で実現するのに適していない場合は、std::bindによってクラスのメンバー関数にコールバック関数をバインドすることもできます.
スマートポインタ初期化(make_unique) c++のポインタ管理を簡素化するため、c++11は標準ライブラリを拡張し、スマートポインタ-std::shared_を発売した.ptr/std::unique_ptr/std::weak_ptr.インテリジェントポインタは、c++言語をより現代的にするために、参照カウントを使用してリソースを自動的に解放します. 標準ライブラリにはstd::make_が用意されています.sharedはstdを初期化します::shared_ptr、newを使用してstdを初期化することを回避しました::shared_ptr.しかし「標準委員会に忘れられた」ため、標準ライブラリはmakeを提供しなかった.uniqueの方法でstd::unique_を初期化します.ptr(c++14で提供されている).そのために私たちは自分でmakeを実現することができます.Unique、コードは以下の通りです.
#include
#include
#include
using namespace std;
class InitClass {
public:
InitClass(initializer_list list) {
for (int l : list)
initializer_list_.emplace_back(l);
}
void PrintInit() {
for (int l : initializer_list_)
cout << l << endl;
}
void Print(initializer_list list) {
for (int l : list)
cout << l << endl;
}
private:
vector initializer_list_;
};
struct A {
double a;
int b;
};
struct B {
B(int a, double b): a_(a), b_(b) {}
private:
int a_;
double b_;
};
int main()
{
//
InitClass i = {1, 2, 3, 4, 5};
i.PrintInit();
cout << endl;
//
i.Print({1, 2, 3});
// POD
vector v = {1, 2, 3, 4};
A a {1.1, 1};
B b {2, 2.2};
return 0;
}
変長パラメータテンプレート(typename...Args)
#include
template
void printf(T value) {
std::cout << value << std::endl;
}
template
void printf(T value, Args... args) {
std::cout << value << std::endl;
printf(args...);
}
int main() {
printf(1, 2, "123", 1.1);
return 0;
}
// -std=c++14
#include
template
auto print(T value, Args... args) {
std::cout << value << std::endl;
return std::initializer_list{([&] {
std::cout << args << std::endl;
}(), value)...};
}
int main() {
print(1, 2.1, "123");
return 0;
}
強いタイプ列挙(enum class)
#include
enum class new_enum : unsigned int {
value1,
value2,
value3 = 888,
value4 = 888
};
template
std::ostream& operator<::value, std::ostream>::type& stream, const T& e) {
return stream << static_cast::type>(e);
}
template
auto to_underlying_type(const T& e) {
return static_cast::type>(e);
}
int main() {
if (new_enum::value3 == new_enum::value4 && 888 == to_underlying_type(new_enum::value3))
{
std::cout << new_enum::value3 << std::endl;
}
return 0;
}
関数オブジェクトパッケージ(std::function)
#include
#include
class A {
public:
using CallBack = std::function;
void SetCallBack(CallBack cb) { call_back_ = cb; }
void CallCallBack() {
if (call_back_)
{
call_back_();
}
}
private:
CallBack call_back_ = nullptr;
};
class B {
public:
B() {
a = std::make_shared();
a->SetCallBack([](){
std::cout << "call A cb in B" << std::endl;
});
a->CallCallBack();
}
private:
std::shared_ptra = nullptr;
};
int main() {
B b;
}
スマートポインタ初期化(make_unique)
#include
template
std::unique_ptr make_unique( Args&& ...args ) {
return std::unique_ptr( new T( std::forward(args)... ) );
}
int main() {
std::unique_ptr p = make_unique(1);
return 0;
}