2017-05-04 18 views
0

##プリプロセッサディレクティブを使用して名前空間とクラス名を連結できますか?Cプリプロセッサを使用した名前空間とクラス名の連結##(double hash)

namespace ns { 
class A 
{ 
public: 
    void print(){ std::cout << "A" << std::endl; }; 
}; 
} 

#define PRINT_NS(E) ([](){ ::ns::##E e; e.print(); }()) 

int main() 
{ 
    PRINT_NS(A); 
} 

それは、次のコンパイルエラーを与える:

13:30: error: pasting "::" and "A" does not give a valid preprocessing token 
17:3: note: in expansion of macro 'PRINT_NS' 

何が::がで考慮されていないされる前のように見えます私は私が何をしたいのかを示すために、この例を書いた

##::がないプリプロセッサトークンプリプロセッサがうまくE(working example)を代用することができるようになりますですので、この場合は

+0

:それ以外の場合は、単一のトークンとして扱われる部品を接着したい、このような何かあなたは '##'と連結しようとしていますか?あなたがそれをしないで、代わりに ':: ns :: E' [それはちょうどうまくいく](http://ideone.com/2uzmrP)をしてください。 – Cornstalks

+0

コードジェネレータで '##'を使用して、名前空間やクラス名の一部であっても、接頭辞を常に同じ方法で追加しようとしていました – Martin

+0

@Martinこの場合、コードジェネレータはチェックする必要があります接頭辞が '::'で終わっているかどうか、そして適切なコードを生成しなければなりません。私はこれが最終的にC++のマクロでこれを処理しようとするより簡単な解決策だと思います。これは、コードジェネレータを変更するためのオプションですか? – Scheff

答えて

0

は、何かを接着する必要はありません。

#define PRINT_NS(E) ([](){ ::ns::E e; e.print(); }()) 

##使用しなければならないときにされているのはなぜ

#define PRINT_NS(E) ([](){ ::ns::My_##E e; e.print(); }()) 
関連する問題