bind()
派生クラスから関数の基本クラスのバージョンを取得したいと考えています。関数は、ベースで保護されているとマークされています。私がそうすると、コードは Clang (Apple LLVM Compiler 4.1) で問題なくコンパイルされますが、g++ 4.7.2 と Visual Studio 2010 の両方でエラーが発生します。エラーは次の行に沿っています: "'Base::foo' : cannot保護されたメンバーにアクセスしてください。」
つまり、参照のコンテキストは実際には 内bind()
にあり、もちろん関数は保護されていると見なされます。しかしbind()
、呼び出し元の関数のコンテキスト (この場合は) を継承してDerived::foo()
、基本メソッドがアクセス可能であると見なすべきではありませんか?
次のプログラムは、この問題を示しています。
struct Base
{
protected: virtual void foo() {}
};
struct Derived : public Base
{
protected:
virtual void foo() override
{
Base::foo(); // Legal
auto fn = std::bind( &Derived::foo,
std::placeholders::_1 ); // Legal but unwanted.
fn( this );
auto fn2 = std::bind( &Base::foo,
std::placeholders::_1 ); // ILLEGAL in G++ 4.7.2 and VS2010.
fn2( this );
}
};
行動の不一致はなぜですか?どちらが正しい?エラーが発生するコンパイラにはどのような回避策がありますか?