テンプレート引数としてメンバ関数へのポインタを渡します。なぜこれが動作しますか?
質問
私は100%私が持っているユースケースのために働くことをいくつかのコードを持っています。誰がどのように、なぜそれが動作説明できる場合、私はただ思ったんだけど。
私はいくつかのスレッド処理するコードと、ネットワーク通信、ユーザにサーバから受信したデータを渡すライブラリのユーザとの間に位置テンプレートクラスを有している。
template <class Bar,
class Baz,
class BazReturnType,
void (Bar::*BarSetterFunction)(const BazReturnType &),
BazReturnType (Baz::*BazGetterFunction)(void) const>
class Foo
{
Foo( Bar *bar )
: m_bar(bar)
{
}
void FooMemberFunction( const Baz *baz )
{
boost::bind( BarSetterFunction, m_bar,
boost::bind( BazGetterFunction, baz )() ) ();
}
Bar *m_bar;
};
このテンプレートはインスタンス化し、そのようなバーやバズの種類に応じて、ライブラリで使用されます:
typedef Foo<MyBar,
MyBaz,
ReturnTypeFromBazGetterFunction,
&MyBar::ActualSetterFunction,
&MyBaz::ActualGetterFunction >
MyFoo;
MyBar *bar = new MyBar;
MyBaz *baz = new MyBaz;
MyFoo *f = new MyFoo( bar );
f->FooMemberFunction( baz );
このすべての作品とブースト::バインドは、それが行く必要がどこの周りにデータを渡すためのゲッター/セッター関数を呼び出します。 をどのように、なぜこのような場合の作業のようにテンプレート引数としてメンバ関数へのポインタを渡すのですか?の
<時間>のコメントを受けて、私は、メンバ関数へのポインタが有効なテンプレート引数だったことに気づいていませんでした。それは私が前に「野生で」見ていたものではないのです。私はそれを試してみました、それが働いていたが、私はそれを期待していませんでした。
解決
私は「標準がそう言うので、」これより行うことが可能である理由より良い説明があると思います:
ポインタ・ツー・メンバーがコンパイル時間(ポインタ・ツー・メンバーが効果的クラスの先頭からメンバーのオフセットされた)で既知の一定値であるので、それが動作する理由があります。従って、それらは、任意の他の整数定数ができるのと同様に、テンプレートのパラメータとして使用することができる。
彼らは、実行時にのみ存在するメモリレイアウトに依存しているため、一方、通常のポインタは、時定数をコンパイルされていません。彼らは、テンプレート引数にすることはできません。
他のヒント
、それはそれが動作するという事実は、あなたに何とか驚くべきことであることを意味します。あなたがを説明しない限り、は、それが驚くべき発見、なぜ質問に答えることは不可能である。
なぜそれが動作しますか?言語仕様は、明示的にそれが機能するものと述べているからです。あなたは、より詳細にあなたの懸念を説明するまで、他の答えは、ありません。