読者です 読者をやめる 読者になる 読者になる

.mmソースファイル内でBoost.Spirit.Qiを使う

Objective-C++

Boost.Spirit.Qiの内部でnilという名前のクラスが使われているので、Objective-C++の文脈(.mm拡張子のソースファイルや、.mmでインクルードされる.h)でこれを使おうとすると、Objective-Cのnilキーワードと衝突してコンパイルエラーになります。
このため、Boost.Spirit.Qiを使うには、.cpp拡張子のソースファイルを作ってC++の文脈で使わなければなりません。


Objective-C++の文脈でBoost.Spirit.Qiを使いたい場合には、Boost.Spirit.Qiの内部で使われているnilの名前を外部から無理矢理書き換えることで、nilとの衝突を回避することができます。
以下がその方法です。

// 一旦nilを消して
#if defined(nil)
    #undef nil
#endif

// Spirit内のnilに別名を付けて
#define nil cpp_nil
#import <boost/spirit/include/qi.hpp>

// nilを定義し直す
#undef nil
#define nil NULL

void f()
{
    NSString* s = nil;
     
    namespace qi = boost::spirit::qi;
 
    const std::string input = "123";
    int result = 0;
      
    std::string::const_iterator it = input.begin();
    qi::parse(it, input.end(), qi::int_, result);
 
    assert(result == 123);
}


nilは単なるNULLのエイリアスです。

// MacTypes.h
...
#define nil NULL

元々のnilの値に依存した実装になってしまっていますが、Objective-C++自体使える環境が限られているのでこの実装で問題になることはあまりないでしょう。