1

...メンバー関数へのポインターは奇妙な動物ですが?

C++ クラスを Lua にバインドするライブラリをコーディングしています。特定の型オブジェクトを Lua スタックにプッシュする (そしてそれらを void* にキャストする) ことによって引き起こされる型消去に対処する必要があります。このため、さまざまな種類のデータ (非 const および const オブジェクト、非 const および const メンバー、および将来的には volatile および non volatile のすべてを 2 倍にするなど) のさまざまなテンプレートの過剰な増殖を避けるために、私は管理します。特定のフラグを設定するだけで、実行時に Lua にバインドされたオブジェクトの constness。

今、私はメンバー関数へのポインターを扱っています。これまでの設計に従って、const メンバー関数へのポインターを非 const メンバー関数に安全にキャストし、同じテンプレートを非 const に再利用し、前述のフラグを使用して実行時に constness を処理できれば幸いです。

しかし、これが本当に可能かどうか疑問に思う別のヒントがあります。以下のコードを検討してください。

#include <iostream>
#include <typeinfo>
using namespace std;

struct A{
    const int a;
    int b;
};

template<typename T> struct tmpl;

template<typename Class, typename FT> struct tmpl<FT(Class::*)>{
    static void f(){
        cout<<"non const"<<endl;
    }
};

//Try commenting this out, code compiles, both A::a and A::b instantiate the first template
template<typename Class, typename FT> struct tmpl<const FT(Class::*)>{
    static void f(){
        cout<<"const"<<endl;
    }
};

int main(){
    cout<<typeid(&A::a).name()<<endl;   //prints "M1AKi"
    tmpl<decltype(&A::a)>::f();         //prints "const"
    cout<<typeid(&A::b).name()<<endl;   //prints "M1Ai"
    tmpl<decltype(&A::b)>::f();         //prints "non const"
    //Let's do what it seems that can be done implicitly (providing only one template specialization) in an explicit way
    int(A::*memb)=(int(A::*))&A::a;
    cout<<typeid(memb).name()<<endl;    //prints "M1Ai"
    tmpl<decltype(memb)>::f();          //prints "non const"
}

これらの動物は自分のサイズを変更することさえできますが、特定の状況ではconst_cast、他のタイプに安全にキャスト (または少なくとも) できるようです (意味がある場合)。

それで、ステップの1つで私の推論はひどく間違っていますか、それともコンパイラに関係なくこれを行うことができますか? const メンバ関数へのポインタで同じようにプレイできますか?

4

1 に答える 1

2

「非 const」特殊化では、FT は単純に const 修飾子を含むと推定されます。消えるのではなく、ただ通過しただけです。

これを試して:

template<typename Class, typename FT> struct tmpl<FT(Class::*)>{
    static void f(){
        if ( std::is_const< FT >::value ) {
            cout<<"const as non const"<<endl;
        } else {
            cout<<"non const"<<endl;
        }
    }
};

http://ideone.com/g2Eie

を殺したい場合はconst、それconst_castが唯一の実行可能なツールです。

于 2012-04-08T13:57:00.067 に答える