(注:"ADL Firewall" という名前は私が勝手につけたもので,一般に認知された呼び方ではないです)
ADL による不用意な関数名の探索を回避しつつ,呼び出し側にそれを意識させない手法.
ある関数あるいは関数テンプレートがあって,それを ADL の対象としたくない場合,
namespace MyLib{
namespace ADLFirewall{
template< class T >
void f( T const &x )
{}
}
}この場合,呼び出し側で MyLib::ADLFirewall::f という形で呼び出す必要があり,わずらわしい.
一方で
namespace MyLib{
template< class T >
void f( T const &x )
{}
}MyLib に定義されたクラスオブジェクトを引数として,関数テンプレート f が名前空間の修飾なしでも ADL によって見えてしまう.
このジレンマを解消するために
namespace MyLib{
namespace ADLFirewall{
template< class T >
void f( T const &x )
{}
}
using ADLFirewall::f;
}とすることで,呼び出し側で MyLib::f と呼び出せて,かつ f が ADL の対象とはならない.
もう1つパターンがあって,他のクラスに対する基底クラスとして指定されることを前提としたクラスで,そのクラスによる不用意な ADL を回避する.
namespace MyLib{
class Base
{};
}これを基底クラスとしたとき
class MyClass
: public MyLib::Base
{};MyClass のオブジェクトを引数とする(名前空間の修飾の無い)関数呼び出しで, MyLib 名前空間に対する ADL が有効になる.これを避けたい場合,
namespace MyLib{
namespace Base_{
class Base
{};
}
using Base_::Base;
}とすれば,
class MyClass
: public MyLib::Base
{};としても, MyLib 名前空間が ADL の対象となることはない.