[[C++ Tips]]
#include(C++TipsMenu,notitle)

* vectorの領域を確保する方法 [#bd10263f]
- vectorでpush_backを行うと、メモリ確保の必要性が起こった場合、倍々でメモリ確保される。
-- 1回目のpush_back  --- メモリを2個分確保
-- 5回目のpush_back  --- メモリを8個分確保
-- 9回目のpush_back  --- メモリを16個分確保
-- 257回目のpush_back ---メモリを512個分確保 (254個分の無駄)
- 257個が上限と判っている場合、
-- reserve(257)とやると、257個分最初に確保される。
- あらかじめサイズが判っている配列は、reserveを使う事でメモリ確保の速度と容量の節約が可能。
 
* クラスメソッドをテンプレートパラメータにする例 [#t8bd518c]
    template <  void (HogeHoge::*FUNC)()>
    void hogeCall(HogeHoge* hoge) {
        (hoge->*FUNC)(); 
    }

   hogeCall<&HogeHoge::SomeMethod>(hoge); // hoge->SomeMethod()が呼ばれます。
   

* typenameをつかうところ [#v957f07d]

 template<typename T> 
 struct Point {
   typedef T value_type;
   T x,y;
 };
 typedef Point<float> Pointf;

 float distance(const Pointf& a, const Pointf& b) {
   return std::sqrt( (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)); 
 }

 template <typename T> 
 typename T::value_type  distance(const T& a, const T& b) {
   return static_cast<typename T::value_type>( std::sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)) ); 
 }

*テンプレートのtypenameとclassの違い [#lb192236]

- typenameとは

型なのか値なのか、曖昧なときに、明示的に型だということを教えてあげるとにきにつかう。

 template <typename T> 
 struct Hoge {
   typedef  Hoho T::Hoho;  // T:Hohoが値なのか型なのか不明
   typedef Hoho typename T:Hoho;   // T:Hohoが型だとうことを示す
 };

- templateパラメータのtypenameとclass

-- templateのパラメータはtypenameとclass両方が利用できる。

 template <typename T> struct hoge;  // OK
 template <class T> struct hoge;          // OK

-- template template パラメータの場合

 template < template <class T> class TT> struct hoge; // OK
 template < template <typename T> class TT> struct hoge; // OK
 template < template <typename T> typename TT> struct hoge; // NG エラー

** templateパラメータのtypenameとは [#ydd022f3]
あらゆる型を想定している時に使う。型にはクラスは含まれるので、クラスでもイミディエートのintやfloatでも良い場合にtypenameを使う。

** templateパラメータのclassとは [#q5407682]
クラスを意味するときにつかう。シンプルなテンプレートパラメータの場合はintやfloatが来てもエラーにならないが、テンプレートパラメータを必要とするテンプレートクラスをパラメータとする場合、classでないとエラーになる。クラス以外の型を入れない場合は、あえてclassを使うという使い方もある。


*グローバル変数の初期化 [#q69b7be7]

- C場合、グローバル領域の変数はすべてゼロクリアされていることが保証されている。

 // グローバル領域はゼロクリア保証
 int a;
 static int b;
 int c[10];
 //プロシージャ内は、指定をしないと値は未定
 hoge()
 {
     static int a;   // staticはゼロクリア保証
     int b; // 未定
     int c[10]; // 未定
     static int d[10]; // ゼロクリア
     int e[10] = {}; // ゼロクリア C++のみ
     int f[10] = {1}; // Cで可能。f[0]は1、f[1]~f[9]は常にゼロでクリアされる。


* 参照型のメンバをもつクラスのコンテナとソート [#j00f0661]


  
 #include "stdio.h"
 #include <list>
 #include <vector>
 #include <algorithm>
 #include <functional>
 
 // 参照を持つクラスのswap
 namespace {
 
     struct Hoge {
         int& instance_;
         Hoge(int& i) : instance_(i)
         {}
         Hoge(const Hoge& h) : instance_(h.instance_) {}
 #if 0
         Hoge& operator = (Hoge h) {
             swap(h);
             return *this;
         }
         void swap(Hoge& h) {
             std::swap(h.instance_, instance_);  // 参照のswapはできない
         }
 #endif
 
         bool operator < (const Hoge& h) const {
             return instance_ < h.instance_;
         }
 
     };
 #if 0
     inline void swap(Hoge& h1, Hoge& h2) {
         h1.swap(h2);
     }
 #endif
     // output用
     void print(const Hoge& h) {
         printf("%d\n", h.instance_);
     }
 
 }
         
 int main(int argc, char* argv[])
 {
         int i1 = 1;
         int i2 = 2;
         int i3 = 3;
         Hoge h1(i1), h2(i2), h3(i3);
         std::vector<Hoge> vectorhoge;  
 //      vectorhoge.push_back(h3); // operator =がないとvector::push_backはでき ない 
 //      vectorhoge.push_back(h2);
 //      vectorhoge.push_back(h1);
 //      std::back_inserter(vectorhoge) = h1;
 //      std::sort(vectorhoge.begin(), vectorhoge.end()); // operator =がないと vector::push_backはできない
 
 
         std::list<Hoge> listhoge;
         listhoge.push_back(h3);
         listhoge.push_back(h2);
         listhoge.push_back(h1);
         std::back_inserter(listhoge) = h1;
         listhoge.sort();
         std::for_each(listhoge.begin(), listhoge.end(), print);
 
         return 0;
 }


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS