...でもpointers to member functions are strange animalsですか?私はconstメンバへのポインタを同じ型であるが非const型に安全にキャストできますか?
私はC++クラスをLuaにバインドするライブラリをコーディングしています。私は特定の型のオブジェクトをLuaスタックにプッシュすることによって引き起こされる型の消去に対処しなければなりません(そしてそれらをvoid *にキャストします)。このため、さまざまな種類のデータ(非constおよびconstオブジェクト、非constおよびconstメンバー、将来的には揮発性および不揮発性の2倍のすべて)の異なるテンプレートの過度の拡散を避けるために、実行時に特定のフラグを設定するだけで、Luaにバインドされたオブジェクトのconstness。
ここでは、メンバー関数のポインタを扱っています。これまでの私の設計では、constメンバ関数へのポインタを非constのものに安全にキャストしてからnon-constのために同じテンプレートを再利用し、実行時に前述のフラグを使って処理することができたら嬉しいです。
しかし、これが本当に可能かどうか疑問に思う別のヒントがあります。以下のコードを考えてみましょう:
#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"
}
それはとてもそのかかわらずthese animals can even change their own size、特定の状況では、あなたが安全にキャストすることができます(あるいは、少なくとも、const_cast
)と思われる彼らは、他のタイプに(彼らは理にかなっている場合)。
コンパイラに関係なく、私の推論はひどく間違っていますか? constメンバ関数へのポインタを使って同じ方法で再生できますか?
meh、私はまだこのテンプレート機械を習得していません。 –
2番目の質問で私を手伝ってもらえますか?constメンバ関数へのポインタと同じ方法で再生できますか?今は不変性は何にも(右か?)含まれていません。しかし、実行時にあなた自身で管理する場合は、 'void(A :: f)()const'を' void(A :: f)() 'にキャストすることは、とにかく安全ですか? –
@LorenzoPistone 'const'修飾子が暗黙の' this'パラメータに適用され、キャストが関数パラメータの型を変更することができないので、メンバ関数はキャストできません。うまくいけば、これはそのような問題ではなく、あなたは正規の引数リストのパラメータの修飾と同様に対処することができます。 – Potatoswatter