public
通常、ネストされた構造体は、所有するクラスとメンバー関数protected
にアクセスできます。ネストされた構造内から基本クラスのメンバー関数をpublic
呼び出すことにも問題はありません。つまり、次のコードがコンパイルされ、正しく機能します。protected
#include <iostream>
class Base
{
public:
Base()
{}
protected:
void baseProtectedFunc()
{
std::cout << __func__ << "Called for Base\n";
}
};
class Derived : public Base
{
public:
explicit Derived() : Base()
{}
void accessBaseProtectedFuncFromNested()
{
Nested myNested( this );
myNested();
}
private:
struct Nested
{
explicit Nested( Derived* ptr ) : derived_( ptr )
{}
void operator()()
{
derived_->baseProtectedFunc();
}
Derived* derived_;
};
};
int main( int, char** )
{
Derived myDerived;
myDerived.accessBaseProtectedFuncFromNested();
return 0;
}
ここで、のタイプmpl::inherit_linearly
を使用して、派生の基本クラスを生成するために使用する次のコードについて考えてみます。mpl::vector
#include <iostream>
#include <typeinfo>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/for_each.hpp>
template<typename T>
class Base
{
public:
Base()
{}
protected:
void baseProtectedFunc()
{
std::cout << __func__ << "Called for Base< " << typeid(T).name() << " >\n";
}
};
typedef boost::mpl::vector< long
, unsigned
, bool
, std::string
> parameter_type_list_t;
typedef boost::mpl::inherit_linearly< parameter_type_list_t
, boost::mpl::inherit< boost::mpl::_1
, Base< boost::mpl::_2 > >
>::type base_types;
class Derived : public base_types
{
public:
explicit Derived() : base_types()
{}
template<typename T>
void accessBaseProtectedFuncFromNested()
{
Nested myNested( this );
myNested.someFunc<T>();
}
private:
struct Nested
{
explicit Nested( Derived* ptr ) : derived_( ptr )
{}
template< typename T >
void someFunc()
{
Base<T>* base = static_cast<Base<T>*>( derived_ );
base->baseProtectedFunc();
}
Derived* derived_;
};
};
int main( int, char** )
{
Derived myDerived;
myDerived.accessBaseProtectedFuncFromNested<unsigned>();
return 0;
}
GCCバージョン4.4.6-3(c++03およびc++0xモード)を使用すると、次のエラーが生成されます。
friend-prot.cpp: In member function ‘void Derived::Nested::someFunc() [with T = unsigned int]’:
friend-prot.cpp:47: instantiated from ‘void Derived::accessBaseProtectedFuncFromNested() [with T = unsigned int]’
friend-prot.cpp:82: instantiated from here
friend-prot.cpp:17: error: ‘void Base<T>::baseProtectedFunc() [with T = unsigned int]’ is protected
friend-prot.cpp:72: error: within this context
関数を作成するとpublic
、コードを呼び出そうとしてコンパイルされ、期待どおりに機能します。
private
Nestedからの呼び出しを転送するだけの派生メンバー関数を追加することで、この問題を回避できます。
struct Nested
{
explicit Nested( Derived* ptr ) : derived_( ptr )
{}
template< typename T >
void operator()()
{
derived_->forwarder<T>();
}
Derived* derived_;
};
template< typename T >
void forwarder()
{
Base<T>::baseProtectedFunc();
}
使用してbaseProtectedFunc()
いるのになぜ電話できないのかわかりません。protected
mpl::inherit
最初の例では基本クラスの保護された関数を呼び出すことができ、2番目の例では呼び出せないのはなぜですか?