2016-03-04 2 views
10

このプロジェクトでは、コンパイラがまだサポートしていないため、C++ 11の機能(例:decltype)を使用できません。私は、C++で基本クラスの型を取得するにはどうすればよいですか?

class Foo: private Bar<Foo> { 
    MAGIC //expands to using Bar<Foo>::Baz; and some others 
    public: 
     void otherFunction(); 
     //... the rest of the class 
}; 

理想等、class宣言をドレッシングまたは中括弧を隠すことなく、引数(下記参照)することなく、好ましくは、マクロ内で、テンプレートパラメータとして現在のクラスを提供することができるようにする必要これはQtのQ_OBJECTマクロのように動作しますが、別の事前コンパイルステップとそれに関連する生成クラスは導入されていません。 typeidは実行時に役立つかもしれませんが、私の目標はビルド時にこれをすべて達成することです。

MAGICマクロを書くたびに、毎回クラス名を繰り返す必要はありません。私は、任意の言語があるとは思わない

#include <iostream> 

template <typename S> 
struct Base : public S { 
    using super = S; 
}; 

template <typename T> 
class Bar 
{ 
public: 
    virtual void f() { std::cout << "Bar" << std::endl; } 
}; 

class Foo : private Base<Bar<int>> 
{ 
public: 
    virtual void f() 
    { 
     std::cout << "Foo"; 
     super::f(); //Calls Bar<int>::f() 
    } 
}; 

class Fii : private Base<Foo> 
{ 
public: 
    virtual void f() 
    { 
     std::cout << "Fii"; 
     super::f(); //Calls Foo::f() 
    } 
}; 


int main() 
{ 
    Fii fii; 
    fii.f(); //Print "FiiFooBar" 
    return 0; 
} 
+0

この質問は「C++で自律型の「self」メンバ型を実装できますか?」(http://stackoverflow.com/q/21143835/)のC++ 03バージョンと思われます。 560648) " –

+1

タイトルを* base clase *に変更すると気になりますか? *クラスを囲むことは、あなたがネストしているように聞こえるし、外側のクラスからどんなタイプになっているかのように思えます。 – NathanOliver

+0

'self'の質問は非常によく似ていますが、あなたが指摘したように、C++ 03で提案されている解決策のようには見えません。 タイトルをもっと明確にするには、確かにタイトルを変更してください。 – multipleinterfaces

答えて

0

あなたは、「プロキシ」の継承を構築するための構造体を使用することができますクラスから基本型を抽出するためにサポートされているメカニズムです。あなたは使用することができます。

オプションについては何1

class Foo: private Bar<Foo> { 

#define BASE_TYPE Bar<Foo> 
    // Use BASE_TYPE in MAGIC 
    MAGIC //expands to using Bar<Foo>::Baz; and some others 
#undef BASE_TYPE 

    public: 
     void otherFunction(); 
     //... the rest of the class 
}; 

オプション2

class Foo: private Bar<Foo> { 

    typedef Bar<Foo> BASE_TYPE; 

    // Use BASE_TYPE in MAGIC 
    MAGIC //expands to using Bar<Foo>::Baz; and some others 

    public: 
     void otherFunction(); 
     //... the rest of the class 
}; 
0

を次のように

template <typename S> 
struct Base : public S{ //always public, access is restricted by inheriting Base properly 
    using super = S; 
}; 

使用方法は、次のようになります(?)

+1

あなたは '#define 'BASE_TYPE' _クラス宣言の前に' class Foo:private BASE_TYPE'と言うことができます。 – mindriot

+3

あるいはクラスに入れ、 'typdef Bar 'のように' #define'の代わりに 'typedef'を使います。 –

+0

@RyanHainingなので、' MAGIC'行の直後に '#undef'があります。 –

1

template<typename T> 
class Base 
{ 
protected: 
    typedef Base<T> MagicBaseType; 
    namespace Baz { } 
}; 

class Derived1 : private Base<Derived1> 
{ 
    using MagicBaseType::Baz; 
} 


class Derived1 : private Base<Derived2> 
{ 
    using MagicBaseType::Baz; 
} 

か、あなたがベースを変更できない場合が定義、テンプレートとmuを使用ltiple継承

template<typename T> 
class Base 
{ 
protected: 
    namespace Baz { } 
}; 

template<typename T> 
class DerivedTemplate : public T 
{ 
protected: 
    typedef typename T BaseType; 
} 

class Derived : public Base<Derived>, public DerivedTemplate<Base<Derived>> 
{ 
using BaseType::Baz; 
} 
0

あなたは本当にあなたがマクロは型引数を取ることによってタイプを繰り返すことなくこれを行うことができ、メンテナンスの頭痛のフォーマットや書き込みを気にしない場合:

#define MAGIC(BASE) \ 
BASE { \ 
    using BASE::baz; 

class Sub : private MAGIC(Base<Foo>) 

    public: 
    void otherFunction(); 
}; 

をしかし、これは作ります私は自分自身についてかなり悪いと感じる

関連する問題