Argument Dependent Lookup Trigger

  • Boost.Serializationで発見。正式名称は不明・・・参照
  • 引数adl_triggerによってADLを意図的に引き起こす
    • ADLは、テンプレートのインスタンス生成地点(2nd phase)から名前を探すことができる
  • カスタマイズする側は、提供される名前空間xxx_overloadにオーバーロードを定義する
  • カスタマイズする型の属する名前空間を用意しなくてよい
    • Boost.Rangeのシンプルな方法では、組み込み型のサポートをあとから追加することはできない(おそらく)
    • その型の名前空間が開けない場合もある
    • コンパイラにADLがなくても、カスタマイズする側に負担がない
  • VC++にはtwo phase lookupはないので注意


[]namespace[] []poost[][] {[]

[]namespace[] []xxx_overload[][] {[]
[]// Welcome home[]
[]struct[] []adl_trigger[][] { };[]
[] }[]


[]namespace[] []xxx_detail[][] {[]

[]template[][]< [][]class[] []T[][] >[]
[]void[] []poost_xxx[][]([][]T[][]& [][]x[][], [][]xxx_overload[][]::[][]adl_trigger[][]) [][]// (1)[]
[] {[]
[]std[][]::[][]cout[][] << [][]"default poost::xxx"[][] << [][]std[][]::[][]endl[][];[]
[] }[]
[] }[]

[]template[][]< [][]class[] []T[][] >[]
[]void[] []xxx[][]([][]T[][]& [][]x[][]) [][]// (2)[]
[] {[]
[]// 1st phase lookup finds (1)[]
[]using[] []namespace[] []xxx_detail[][];[]

[]// 2nd phase ADLookup finds (3)[]
[]poost_xxx[][]([][]x[][], [][]xxx_overload[][]::[][]adl_trigger[][]());[]
[] }[]

[]} [][]// namespace poost[]

[]// An important function[]
[]template[][]< [][]class[] []T[][] >[]
[]void[] []yyy[][]([][]T[][]& [][]x[][])[]
[]{[]
[]// non-dependent name[]
[]// 1st phase lookup only[]
[]poost[][]::[][]xxx[][]([][]x[][]); [][]// always (2)[]
[]// ...[]
[]}[]

[]// user-defined customization[]
[]namespace[] []poost[][] { [][]namespace[] []xxx_overload[][] {[]

[]inline void[] []poost_xxx[][]([][]int[] []x[][], [][]adl_trigger[][]) [][]// (3)[]
[] {[]
[]std[][]::[][]cout[][] << [][]"int's poost::xxx"[][] << [][]std[][]::[][]endl[][];[]
[] }[]

[]} } [][]// namespace poost::xxx_overload[]

[]int[] []main[][]()[]
[]{[]
[]int[] []i[][];[]
[] ::[][]yyy[][]([][]i[][]);[]

[]return[] []0[][];[]
[]} [][]// <- Point of Instantiation of ::yyy<int>(int&) and poost::xxx<int>(int&)[]