2016-01-27 10 views
17

型宣言の中に型名を明示せずに宣言された(周囲の)型自体にtypedefを構築する方法はありますか?C言語で囲む型にtypedef

例:

class X 
{ 
    public: 
    typedef <fill in magic here> MyType; 
    //... 
}; 

背景: これが初見で愚かなようです。マクロを使用してデータクラスのコンパイル時反映を構築するため、これが必要です。 したがって、データクラスの宣言に挿入されている型が処理される必要があるマクロが挿入されています。 これまで私はMSVCとg ++のための実用的なソリューションを見つけました。どちらも実装の欠陥であると私は思っています。したがって、新しいバージョンでは動作しない可能性があります。 Clangはこれらのソリューションのいずれかを「食べて」いません。

私の現在のMSVCソリューションは、メソッドを定義し、そのアドレスでアドレスを取得し、そのクラスの型を「返す」小さなヘルパーを呼び出します。 (Clangとg ++はクラス名を含むメソッドのフルネームを期待しています)。

私の現在のg ++​​ソリューションは、返品タイプがstd::remove_reference(decltype(*this))の静的メソッドを定義しています。 (ClangとMSVCは、静的コンテキストでthisを許可しません)。

私は絶対に標準に準拠したソリューションを好みますが、clangの特別なソリューションも今のところ大丈夫です。

何も動作しない場合は、クラス名をマクロに渡す必要がありますが、マクロを使用したコードがたくさんあるので、これを避けようとしています。

EDIT:(私は必要なものを明確にすることができる)反射の仕組みでサンプルの追加:

class X : public Y 
{ 
    public: 
    //.. constructor and such stuff... 

    int a; 
    double b; 
    std::string c; 

    CLASSHEAD(Y) 
     FIELD(a) 
     FIELD(b) 
     FIELD(c) 
    CLASSFOOT 
}; 

CLASSHEADtypedefを定義する必要がマクロです。引数が基本クラスを受け取るのはVAR_ARGSマクロです。次のように:最初の引数としてクラス名を与えることができます(この例ではCLASSHEAD(X, Y)になります)。しかし、私はほぼ周囲のタイプをtypedef'ingなど「を単に」タスクの解決策がないことを想像することはできません...

+0

実際、 'typedef X MyType;'を実行して、マクロに 'MyType'を使用させることができないのはなぜわかりませんか? – BoBTFish

+0

このメカニズムを使用すると予想されるクラスはすべて、同じベースから継承しますか? (私はCRTP回答を元に戻すことができます)。 – BoBTFish

+1

私がこれを必要と思う唯一の理由は、機能シグニチャです。関数自体の中では、上記のように 'typedef std :: remove_reference(decltype(* this)):: type MyType;'を使用します。これらの関数をテンプレートにして、 'static_assert(std :: is_same :: value);'を作成することができます。きれいではない、何も良いと思うことはできません。 – BoBTFish

答えて

-3

マクロのクラス名を使用するNohtingが機能するので、唯一の解決策です

2

これはまさにあなたの仕様を満たしていないが、私はそのかなり近いと思う:

class X 
{ 
//Stuff... 

//Use Macros to add: 
struct MyType; 

//Use class closing macro to insert variable between class-ending brace and semicolon  


} TYPE_VAR; 
//Perhaps add random stuff to TYPE_VAR name to avoid collisions, like __FILE__ 
struct decltype(TYPE_VAR)::MyType 
{ 
    typedef decltype(TYPE_VAR) V; 
}; 

は、次に例えば

X::MyType::V 

を使用してXの型にアクセスする、単純化されたCLASSFOOTは次のようになります。

#define CLASSFOOT /*Your classfoot here*/ } TYPE_VAR; struct decltype(TYPE_VAR)::MyType {typedef decltype(TYPE_VAR) V; 
//No }; at end on purpose- this will come from the class in which you placed CLASSFOOT 

これはあなたの目的には十分ですか?

+0

「MyType :: V」は、「X」の定義の中で使用できないということです(OPが必要と思う機能) –

+1

これは元の質問には答えません。 – mmmmmmmm

0

すでにマクロを使用しているので、あなたはhttps://stackoverflow.com/a/21143997/2173029

#define CLASS_WITH_MY_TYPE(ClassName) \ 
    class ClassName     \ 
    {         \ 
     using MyType = ClassName; 

このソリューションを使用することができます。そして@クリスは、リンクを言及し、元の答えだったので

コミュニティのwikiとしてマーク
CLASS_WITH_MY_TYPE(X) 
public: 
    struct Y 
    { 
    using T = MyType; 
    }; 
}; 

static_assert(std::is_same<X, typename X::Y::T>::value, ""); 

のように使用します@Bartek Banachewiczによって投稿されました

+0

@RüdigerStevens私はあなたが 'CLASSHEAD'マクロを意味すると思いました。 – Rumburak