#contents
#setlinebreak(on)


*テンプレート使用時の primary-expression token なビルドエラー対応方法メモ [#kbadf5ec]
テンプレートメソッド内で別のテンプレートを呼び出している箇所で、特定のコンパイラでコンパイル時に
*(C++11)テンプレート使用時の primary-expression token なビルドエラー対応方法メモ [#kbadf5ec]
C++11のテンプレートメソッド内で別のテンプレートを呼び出している箇所で、特定のコンパイラでコンパイル時に
 error: expected primary-expression before '>' token
なエラーが出た場合の解決方法メモです。
 // テンプレートなクラス
 template<typename T1>
 class TemplateClass
 {
 public:
 	template<typename T2> T2 func() { return T2(); }
 };
 
 // テンプレートな関数
 template<typename T1, typename T2>
 void templateFunction()
 {
 	TemplateClass<T1>	t;
 	t.func<T2>();		// < ここでエラーがでます
 }
 
 // templateFunctionをコール
 void main()
 {
 	templateFunction<int,float>();
 }
上記のコードをビルドするとこんなエラーが出ます。
 hoge.cpp: In function 'void templateFunction()':
 hoge.cpp:xxx:xxx: error: expected primary-expression before '>' token
    t.func<T2>();
             ^
 hoge.cpp:xxx:xxx: error: expected primary-expression before ')' token
    t.func<T2>();
               ^
templateFunction()内の
 t.func<T2>();
を以下のように書き換えるとビルドエラーが解消されます。
 t.template func<T2>();

参考
http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords
*staticなメンバ変数の初期化 [#j1c418ca]
Hoge.h
 class Hoge {
 public:
 	static func();
 private:
 	static std::vector<int>	m_vector;
 	static std::bitset<16>	m_bitset;
 	static int		m_array[16];
 };
Hoge.cpp
 Hoge::func()
 {
 	m_vector.clear();
 	m_bitset.reset();
 	m_array[0] = 0;
 }
という風にしてしまうと、LNK2001の外部参照が未解決リンクエラーが出てしまいます。
staticなメンバ変数は、ヘッダ上では宣言しているだけなので、実体の確保はソース(cpp)側で行う必要があります。
Hoge.cppのfunc()の前に
 std::vector<int>	Hoge::m_vector;
 std::bitset<16>	Hoge::m_bitset;
 int			Hoge::m_array[16];
を追記して、暗黙の初期化を行うようにすればリンクエラーは解消されます。

*クラスのメンバ関数ポインタをアップキャストして使用する [#sb89181d]
宣言部
 class FuncClassBase;
 typedef void			(FuncClassBase::*FuncClassCallback)();
 class FuncClassBase {
 public:
 	FuncClassCallback	m_callback;
 };
  
 class FuncClassA : public FuncClassBase {
 	int		a;
 public:
 	FuncClassA()
 	{
 		a = 99;
 	}
 	void			funcA()
 	{
 		printf( "funcA %d\n", a );
 	}
 };
実装部
 FuncClassBase	funcClassBase;
 FuncClassA	funcClassA;
 
 // static_castすればFuncClassBaseの関数ポインタ型のFuncClassCallbackにFuncClassAの関数ポインタを代入する事ができる
 FuncClassCallback fc = static_cast<FuncClassCallback>(&FuncClassA::funcA);
 
 (funcClassA.*fc)(); // これは安全
 (funcClassBase.*fc)(); // これは危険。やっちゃだめ
 
 // このやり方も大丈夫
 funcClassA.m_callback = static_cast<FuncClassCallback>(&FuncClassA::funcA);
 (funcClassA.*funcClassA.m_callback)();
*クラスのメンバ関数ポインタのエラーに関するメモ [#p515bb73]
 class Hoge
 {
 public:
 	void	(Hoge::*m_func)(void);
 	void Call()
 	{
 		this->m_func = &Hoge::Func;
 
 		(this->*m_func)();
 	}
 	void Func(void)
 	{
 		printf("func\n");
 	}
 };

下記のエラーは

 error C3867: 'Hoge::Func': function call missing argument list; use '&Hoge::Func' to create a pointer to member

こうやると、
 this->m_func = Func;
出るエラーなので、
 this->m_func = &Hoge::Func;
こうする。


*templateクラス内templateクラスのstaticメンバ変数を初期化する [#j611f962]
templateクラス内のtemplateクラスのstaticメンバ変数に初期値を入れたい場合、
 template <typename T1>
 class Hoge1
 {
   template< typename T2 >
   class Hoge2
   {
      static int id_; // これを初期化したい時
   };
 };
↓こんな風に書けば初期値を入れられる。
 template<typename T1>
 template<typename T2>
 int Hoge1<T1>::Hoge2<T2>::id_ = (sizeof(T1) * sizeof(T2));


*オペレータ [#p5fb07ba]
-まとめメモ[[【C/C++】 演算子のオーバーロード: 日々此精進:http://murakan.cocolog-nifty.com/blog/2009/04/c-4b42.html]]


*TIPS [#s22e960d]
-イテレータのforループでは前置インクリメントを使用する
 for (it=v.begin(); it!=v.end(); it++) {}
より
 for (it=v.begin(); it!=v.end(); ++it) {}
の方が、速度、メモリ効率が良い。
http://d.hatena.ne.jp/cubicdaiya/20080606/1212695409
http://ch.cri-mw.co.jp/hirase/275.html
-c#みたいに #region でコードを折りたたみたい場合は #pragma region を使う。
 #pragma region 折りたたみ
 // ここが折りたたまれます。
 int a = 10;
 a = 20;
 #pragma endregion
-警告
 warning C4311: '型キャスト' : ポインタを 'void *' から 'unsigned int' へ切り詰めます。
64bit環境で問題が起きます。
1.uintptr_tのような移植可能な型を利用する
2./Wp64オプション(構成プロパティ - C/C++ - 全般 - 64 ビット移植への対応)を指定しない(いいえにする)
のどちらかで対応可能です。
-__DATE__とか__TIME__とか__FILE__とか__LINE__とかをワイド文字列にする。
  const wchar_t* s = __DATE__;
としようとするとコンパイルエラーになってしまう。
以下のようなマクロを使うとうまくいく。
  #define WIDEN2(x) L ## x
  #define WIDEN(x) WIDEN2(x)
  const wchar_t* s = WIDEN(__DATE__);
参考サイト
http://msdn.microsoft.com/en-us/library/b0084kay%28v=vs.80%29.aspx

    ホーム 一覧 単語検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS