template な friend
テンプレートクラスや関数を friend にする方法のメモ.危険性についても言及.
方法
こんな感じで書く:
class TTest { ... template<typename T> friend void Func(TTest &test,const T &x); }
サンプル:
#include <iostream> class TTest { public: TTest() : x(-1) {} const int& X() const {return x;} private: int x; template<typename T> friend void Func(TTest &test,const T &x); }; template<typename T> void Func(TTest &test,const T &x) { test.x= x; } using namespace std; #define print(var) std::cout<<#var"= "<<(var)<<std::endl int main(int argc, char**argv) { TTest test; print(test.X()); Func(test,3.14); print(test.X()); return 0; }
結果:
test.X()= -1 test.X()= 3
危険性
しかし,通常の friend 関数やクラスと比べて,テンプレート関数やクラスを friend にすると危険性が増す.
つまり,ユーザが friend 関数やクラスを特殊化したものを定義できる可能性がある.
例えば,上のコードに,ユーザは
template<> void Func(TTest &test,const int &x) { test.x= 100000; }
という特殊化を(悪意を持って)追加できる.