ところでこのソースコードを見てくれ。こいつをどう思う?
http://ideone.com/3IjA2
#include <iostream> namespace A { // 適当な実装補助クラス class noncopyable { noncopyable( noncopyable const& ); void operator=( noncopyable const& ); protected: noncopyable(){} }; // それと全然関係ないユーティリティ関数な何か template<class T> void f( T& x ) { std::cout << "A::f" << std::endl; } } // ここまでヘッダファイルだとする // noncopyable と f が別のヘッダだったりすると素晴らしい。 namespace B { // 実装補助に private 継承を使う // テンプレートパラメータでもよし class hoge : A::noncopyable { // たまたまユーティリティ関数と同じ名前の関数がある // この f は ADL でしか呼ばれない friend void f( hoge const& ) { std::cout << "B::f" << std::endl; } }; } int main() { B::hoge x; f(x); // ADL で呼ぶ。当然 B::f を期待 }
結果:
A::f
すごく……邪悪です……。
ちなみに A::f の宣言が
namespace A { template<class T> void f( T && x ); // && で何かに転送する }
となっていても、やはり A::f が呼ばれます。