Cocos2d-x 3.2 の開発環境構築手順

3.0から放置していましたが、3.1をすっとばして、Cocos2d-x 3.2 の開発環境手順をまとめました。

ぎじゅつめも | Cocos2d-x開発環境の構築

3.0 で作成しているローカルのプロジェクトを3.2にアップデートする作業をしないとだめなんですが、それはまた後日・・・。

(C++11)テンプレート使用時の primary-expression token なビルドエラー対応方法メモ

C++11のテンプレートメソッド内で別のテンプレートを呼び出している箇所で、特定のコンパイラでコンパイル時、
error: expected primary-expression before ‘>’ token
なエラーに悩んでしまったので解決方法をメモします。
今まで見たことないので多分C++11からの仕様だと思います。

コードは以下のような感じになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// テンプレートなクラス
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>();
}

上記のコードをビルドするとこんなエラーが出ます。

1
2
3
4
5
6
7
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>();
              ^

VisualStudioでは出ずに、gccで出ます。
templateFunction()内の

1
t.func<T2>();

を以下のように書き換えるとビルドエラーが解消されます。

1
t.template func<T2>();

静的コンストラクタ

クラスの静的コンストラクタを実現する方法を紹介します。
起動時に一度だけ行いたい処理を書く時などに便利です。
ただし、他のstaticなオブジェクトと同じく、初期化順番は保証されない点は注意してください。

ヘッダはこんな感じ。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Hoge
{
private:
    //! 静的コンストラクタ用のprivateな構造体
    struct Construct
    {
        Construct()
        {
            // ここに初期化処理を書きます
            sm_hoge = 0;
        }
    };
private:
    static Construct    sm_construct;   //!< 静的コンストラクタ
    static int          sm_hoge;
};

cpp側はこんな感じになります。

1
2
Hoge::Construct Hoge::sm_construct;
int             Hoge::sm_hoge = 0;

ご覧のとおり、今回のパターンだとsm_hogeはもともと0で初期化しているので静的コンストラクタで処理している内容に意味はなかったりします。

staticなメンバ変数の初期化

Hoge.h

1
2
3
4
5
6
7
8
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

1
2
3
4
5
6
Hoge::func()
{
    m_vector.clear();
    m_bitset.reset();
    m_array[0] = 0;
}

という風にしてしまうと、LNK2001の外部参照が未解決リンクエラーが出てしまいます。
staticなメンバ変数は、ヘッダ上では宣言しているだけなので、実体の確保はソース(cpp)側で行う必要があります。
Hoge.cppのfunc()の前に

1
2
3
std::vector<int>  Hoge::m_vector;
std::bitset<16>   Hoge::m_bitset;
int               Hoge::m_array[16];

を追記して、暗黙の初期化を行うようにすればリンクエラーは解消されます。