アクセス制御は、明示的なテンプレートのインスタンス化()への引数には適用されません[temp.explicit]/12
。これを利用して、プライベートメンバーにパブリックアクセスを提供できます(litbの厚意により)。
最初にいくつかのセットアップコード:
template<typename Tag>
struct result {
/* export it ... */
typedef typename Tag::type type;
static type ptr;
};
template<typename Tag>
typename result<Tag>::type result<Tag>::ptr;
template<typename Tag, typename Tag::type p>
struct rob : result<Tag> {
/* fill it ... */
struct filler {
filler() { result<Tag>::ptr = p; }
};
static filler filler_obj;
};
template<typename Tag, typename Tag::type p>
typename rob<Tag, p>::filler rob<Tag, p>::filler_obj;
今の定義Point
:
class Point
{
public:
Point() : m_i(0) {}
void PrintPrivate(){cout << m_i << endl; }
private:
int m_i;
};
次にresult<Pointm_i>::ptr
、明示的にインスタンス化して入力しますrob<Pointm_i, &Point::m_i>
。これは明示的なテンプレートのインスタンス化であるため、アクセス制御は適用されません。
struct Pointm_i { typedef int Point::*type; };
template class rob<Pointm_i, &Point::m_i>;
そして、プライベートメンバーにアクセスします。
void ChangePrivate ( Point &i ) { (i.*result<Pointm_i>::ptr)++; }
int main()
{
Point sPoint;
sPoint.PrintPrivate();
ChangePrivate(sPoint);
sPoint.PrintPrivate();
}