@@ -214,42 +214,42 @@ <h1 itemprop="name"><span class="token">ADLを無効にする関数定義</span>
214214< div itemprop ="articleBody "> < p > C++20から、< code > < a href ="../../reference/iterator.html "> <iterator></ a > </ code > や< code > < a href ="../../reference/algorithm.html "> <algorithm></ a > </ code > にある一部の関数テンプレートに対して、よりジェネリックに定義し直されたものが< code > std::ranges</ code > 名前空間に同じ名前で追加されている。</ p >
215215< p > 規格書においてはこれらの関数テンプレートは< a class ="cpprefjp-defined-word " data-desc ="実引数依存の名前探索 (Argument Dependent Lookup)。引数の型が所属する名前空間の関数を探索する言語機能 "> ADL</ a > で発見されない事を規定している。< br />
216216そのうちの一つである< code > < a href ="../../reference/iterator/ranges_distance.html "> std::ranges::distance</ a > </ code > を例として上げると、次のような場合に< a class ="cpprefjp-defined-word " data-desc ="実引数依存の名前探索 (Argument Dependent Lookup)。引数の型が所属する名前空間の関数を探索する言語機能 "> ADL</ a > を無効化して呼び出される。</ p >
217- < p > < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="kt "> void</ span > < span class ="nf "> foo</ span > < span class ="p "> ()</ span > < span class ="p "> {</ span >
218- < span class ="c1 "> // std::ranges名前空間を取り込む</ span >
219- < span class ="k "> using</ span > < span class ="k "> namespace</ span > < span class ="n "> std</ span > < span class ="o "> ::</ span > < span class ="n "> ranges</ span > < span class ="p "> ;</ span >
217+ < p > < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="kt "> void</ span > < span class =" w " > </ span > < span class ="nf "> foo</ span > < span class ="p "> ()</ span > < span class =" w " > </ span > < span class ="p "> {</ span >
218+ < span class =" w " > </ span > < span class ="c1 "> // std::ranges名前空間を取り込む</ span >
219+ < span class =" w " > </ span > < span class ="k "> using</ span > < span class =" w " > </ span > < span class ="k "> namespace</ span > < span class =" w " > </ span > < span class ="nn "> std</ span > < span class ="o "> ::</ span > < span class ="nn "> ranges</ span > < span class ="p "> ;</ span >
220220
221- < span class ="n "> < a href ="../../reference/vector/vector.html "> std::vector</ a > </ span > < span class ="o "> <</ span > < span class ="kt "> int</ span > < span class ="o "> ></ span > < span class ="n "> vec</ span > < span class ="p "> {</ span > < span class ="mi "> 1</ span > < span class ="p "> ,</ span > < span class ="mi "> 2</ span > < span class ="p "> ,</ span > < span class ="mi "> 3</ span > < span class ="p "> };</ span >
222- < span class ="n "> distance</ span > < span class ="p "> (</ span > < span class ="n "> begin</ span > < span class ="p "> (</ span > < span class ="n "> vec</ span > < span class ="p "> ),</ span > < span class ="n "> end</ span > < span class ="p "> (</ span > < span class ="n "> vec</ span > < span class ="p "> ));</ span > < span class ="c1 "> // #1</ span >
221+ < span class =" w " > </ span > < span class ="n "> < a href ="../../reference/vector/vector.html "> std::vector</ a > </ span > < span class ="o "> <</ span > < span class ="kt "> int</ span > < span class ="o "> ></ span > < span class =" w " > </ span > < span class ="n "> vec</ span > < span class ="p "> {</ span > < span class ="mi "> 1</ span > < span class ="p "> ,</ span > < span class ="mi "> 2</ span > < span class ="p "> ,</ span > < span class ="mi "> 3</ span > < span class ="p "> };</ span >
222+ < span class =" w " > </ span > < span class ="n "> distance</ span > < span class ="p "> (</ span > < span class ="n "> begin</ span > < span class ="p "> (</ span > < span class ="n "> vec</ span > < span class ="p "> ),</ span > < span class =" w " > </ span > < span class ="n "> end</ span > < span class ="p "> (</ span > < span class ="n "> vec</ span > < span class ="p "> ));</ span > < span class =" w " > </ span > < span class ="c1 "> // #1</ span >
223223< span class ="p "> }</ span >
224224</ code > </ pre > </ div >
225225</ p >
226226< p > < code > #1</ code > の箇所で呼ばれる関数は< code > std::distance</ code > ではなく< code > std::ranges::distance</ code > となる。< a class ="cpprefjp-defined-word " data-desc ="同名の関数を異なる引数・テンプレート・制約などで複数定義すること。または同名の関数の集合 "> オーバーロード</ a > の半順序においてはより特殊化されている関数テンプレートが選択されると言うルールがあり、< code > std::distance</ code > の方が< code > std::ranges::distance</ code > よりも特殊化されている(イテレータ型と番兵型が1つのテンプレートパラメータで指定されている)が、それとは関係なく常に< code > std::ranges::distance</ code > が選択される。</ p >
227227< p > これは、< code > std::ranges</ code > 以下にあるこのような規定を持つ関数が通常の(修飾・非修飾名に対する)名前探索で見えているときは必ずそちらが選択されると言う事であり、その際は< a class ="cpprefjp-defined-word " data-desc ="実引数依存の名前探索 (Argument Dependent Lookup)。引数の型が所属する名前空間の関数を探索する言語機能 "> ADL</ a > が行われない(無効化される)事を規定している。</ p >
228228< p > < code > std::ranges</ code > 名前空間に追加される関数テンプレート群は、同名の< code > std</ code > 名前空間直下にある既存のものに対してC++20の< code > <ranges></ code > が規定するイテレータ/rangeコンセプトに適合するように再設計されたものであり、このような規定はC++20以降古い関数が意図せず使用されないようにするための処置であると考えられる。</ p >
229229< p > この性質は通常の関数では実現できず、これらの関数テンプレートは実のところ関数テンプレートではない。おそらく関数オブジェクトとして実装されるものと思われる。以下は、関数オブジェクトによる実装例である:</ p >
230- < p > < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="cp "> #include</ span > < span class =" cpf " > < a href ="../../reference/iostream.html "> <iostream></ a > </ span > < span class =" cp " > </ span >
231- < span class ="cp "> #include</ span > < span class =" cpf " > < a href ="../../reference/iterator.html "> <iterator></ a > </ span > < span class =" cp " > </ span >
232- < span class ="cp "> #include</ span > < span class =" cpf " > < a href ="../../reference/vector.html "> <vector></ a > </ span > < span class =" cp " > </ span >
230+ < p > < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="cp "> #include < a href ="../../reference/iostream.html "> <iostream></ a > </ span >
231+ < span class ="cp "> #include < a href ="../../reference/iterator.html "> <iterator></ a > </ span >
232+ < span class ="cp "> #include < a href ="../../reference/vector.html "> <vector></ a > </ span >
233233
234- < span class ="k "> namespace</ span > < span class ="n "> my_range</ span > < span class ="p "> {</ span >
235- < span class ="k "> struct</ span > < span class ="n "> distance_t</ span > < span class ="p "> {</ span >
236- < span class ="k "> template</ span > < span class ="o "> <</ span > < span class ="k "> class</ span > < span class ="nc "> Iterator</ span > < span class ="o "> ></ span >
237- < span class ="k "> auto</ span > < span class ="k "> operator</ span > < span class ="p "> ()(</ span > < span class ="n "> Iterator</ span > < span class ="n "> first</ span > < span class ="p "> ,</ span > < span class ="n "> Iterator</ span > < span class ="n "> last</ span > < span class ="p "> )</ span > < span class ="k "> const</ span > < span class ="p "> {</ span >
238- < span class ="n "> < a href ="../../reference/iostream/cout.html "> std::cout</ a > </ span > < span class ="o "> <<</ span > < span class ="s "> "call my_distance"</ span > < span class ="o "> <<</ span > < span class ="n "> < a href ="../../reference/ostream/endl.html "> std::endl</ a > </ span > < span class ="p "> ;</ span >
239- < span class ="kt "> int</ span > < span class ="n "> n</ span > < span class ="o "> =</ span > < span class ="mi "> 0</ span > < span class ="p "> ;</ span >
240- < span class ="k "> for</ span > < span class ="p "> (;</ span > < span class ="n "> first</ span > < span class ="o "> !=</ span > < span class ="n "> last</ span > < span class ="p "> ;</ span > < span class ="o "> ++</ span > < span class ="n "> first</ span > < span class ="p "> ,</ span > < span class ="o "> ++</ span > < span class ="n "> n</ span > < span class ="p "> )</ span > < span class ="p "> {}</ span >
241- < span class ="k "> return</ span > < span class ="n "> n</ span > < span class ="p "> ;</ span >
242- < span class ="p "> }</ span >
243- < span class ="p "> };</ span >
244- < span class ="k "> constexpr</ span > < span class ="kr "> inline</ span > < span class ="n "> distance_t</ span > < span class ="n "> distance</ span > < span class ="p "> {};</ span >
234+ < span class ="k "> namespace</ span > < span class =" w " > </ span > < span class ="nn "> my_range</ span > < span class =" w " > </ span > < span class ="p "> {</ span >
235+ < span class =" w " > </ span > < span class ="k "> struct</ span > < span class =" w " > </ span > < span class ="nc "> distance_t</ span > < span class =" w " > </ span > < span class ="p "> {</ span >
236+ < span class =" w " > </ span > < span class ="k "> template</ span > < span class =" w " > </ span > < span class ="o "> <</ span > < span class ="k "> class</ span > < span class =" w " > </ span > < span class ="nc "> Iterator</ span > < span class ="o "> ></ span >
237+ < span class =" w " > </ span > < span class ="k "> auto</ span > < span class =" w " > </ span > < span class ="k "> operator</ span > < span class ="p "> ()(</ span > < span class ="n "> Iterator</ span > < span class =" w " > </ span > < span class ="n "> first</ span > < span class ="p "> ,</ span > < span class =" w " > </ span > < span class ="n "> Iterator</ span > < span class =" w " > </ span > < span class ="n "> last</ span > < span class ="p "> )</ span > < span class =" w " > </ span > < span class ="k "> const</ span > < span class =" w " > </ span > < span class ="p "> {</ span >
238+ < span class =" w " > </ span > < span class ="n "> < a href ="../../reference/iostream/cout.html "> std::cout</ a > </ span > < span class =" w " > </ span > < span class ="o "> <<</ span > < span class =" w " > </ span > < span class ="s "> "call my_distance"</ span > < span class =" w " > </ span > < span class ="o "> <<</ span > < span class =" w " > </ span > < span class ="n "> < a href ="../../reference/ostream/endl.html "> std::endl</ a > </ span > < span class ="p "> ;</ span >
239+ < span class =" w " > </ span > < span class ="kt "> int</ span > < span class =" w " > </ span > < span class ="n "> n</ span > < span class =" w " > </ span > < span class ="o "> =</ span > < span class =" w " > </ span > < span class ="mi "> 0</ span > < span class ="p "> ;</ span >
240+ < span class =" w " > </ span > < span class ="k "> for</ span > < span class =" w " > </ span > < span class ="p "> (;</ span > < span class ="n "> first</ span > < span class =" w " > </ span > < span class ="o "> !=</ span > < span class =" w " > </ span > < span class ="n "> last</ span > < span class ="p "> ;</ span > < span class =" w " > </ span > < span class ="o "> ++</ span > < span class ="n "> first</ span > < span class ="p "> ,</ span > < span class =" w " > </ span > < span class ="o "> ++</ span > < span class ="n "> n</ span > < span class ="p "> )</ span > < span class =" w " > </ span > < span class ="p "> {}</ span >
241+ < span class =" w " > </ span > < span class ="k "> return</ span > < span class =" w " > </ span > < span class ="n "> n</ span > < span class ="p "> ;</ span >
242+ < span class =" w " > </ span > < span class ="p "> }</ span >
243+ < span class =" w " > </ span > < span class ="p "> };</ span >
244+ < span class =" w " > </ span > < span class ="k "> constexpr</ span > < span class =" w " > </ span > < span class ="kr "> inline</ span > < span class =" w " > </ span > < span class ="n "> distance_t</ span > < span class =" w " > </ span > < span class ="n "> distance</ span > < span class ="p "> {};</ span >
245245< span class ="p "> }</ span >
246246
247- < span class ="kt "> int</ span > < span class ="n "> main</ span > < span class ="p "> ()</ span > < span class ="p "> {</ span >
248- < span class ="k "> using</ span > < span class ="k "> namespace</ span > < span class ="n "> my_range</ span > < span class ="p "> ;</ span >
247+ < span class ="kt "> int</ span > < span class =" w " > </ span > < span class ="n "> main</ span > < span class ="p "> ()</ span > < span class =" w " > </ span > < span class ="p "> {</ span >
248+ < span class =" w " > </ span > < span class ="k "> using</ span > < span class =" w " > </ span > < span class ="k "> namespace</ span > < span class =" w " > </ span > < span class ="nn "> my_range</ span > < span class ="p "> ;</ span >
249249
250- < span class ="n "> < a href ="../../reference/vector/vector.html "> std::vector</ a > </ span > < span class ="o "> <</ span > < span class ="kt "> int</ span > < span class ="o "> ></ span > < span class ="n "> v</ span > < span class ="o "> =</ span > < span class ="p "> {</ span > < span class ="mi "> 1</ span > < span class ="p "> ,</ span > < span class ="mi "> 2</ span > < span class ="p "> ,</ span > < span class ="mi "> 3</ span > < span class ="p "> };</ span >
251- < span class ="kt "> int</ span > < span class ="n "> n</ span > < span class ="o "> =</ span > < span class ="n "> distance</ span > < span class ="p "> (</ span > < span class ="n "> begin</ span > < span class ="p "> (</ span > < span class ="n "> v</ span > < span class ="p "> ),</ span > < span class ="n "> end</ span > < span class ="p "> (</ span > < span class ="n "> v</ span > < span class ="p "> ));</ span >
252- < span class ="n "> < a href ="../../reference/iostream/cout.html "> std::cout</ a > </ span > < span class ="o "> <<</ span > < span class ="n "> n</ span > < span class ="o "> <<</ span > < span class ="n "> < a href ="../../reference/ostream/endl.html "> std::endl</ a > </ span > < span class ="p "> ;</ span >
250+ < span class =" w " > </ span > < span class ="n "> < a href ="../../reference/vector/vector.html "> std::vector</ a > </ span > < span class ="o "> <</ span > < span class ="kt "> int</ span > < span class ="o "> ></ span > < span class =" w " > </ span > < span class ="n "> v</ span > < span class =" w " > </ span > < span class ="o "> =</ span > < span class =" w " > </ span > < span class ="p "> {</ span > < span class ="mi "> 1</ span > < span class ="p "> ,</ span > < span class =" w " > </ span > < span class ="mi "> 2</ span > < span class ="p "> ,</ span > < span class =" w " > </ span > < span class ="mi "> 3</ span > < span class ="p "> };</ span >
251+ < span class =" w " > </ span > < span class ="kt "> int</ span > < span class =" w " > </ span > < span class ="n "> n</ span > < span class =" w " > </ span > < span class ="o "> =</ span > < span class =" w " > </ span > < span class ="n "> distance</ span > < span class ="p "> (</ span > < span class ="n "> begin</ span > < span class ="p "> (</ span > < span class ="n "> v</ span > < span class ="p "> ),</ span > < span class =" w " > </ span > < span class ="n "> end</ span > < span class ="p "> (</ span > < span class ="n "> v</ span > < span class ="p "> ));</ span >
252+ < span class =" w " > </ span > < span class ="n "> < a href ="../../reference/iostream/cout.html "> std::cout</ a > </ span > < span class =" w " > </ span > < span class ="o "> <<</ span > < span class =" w " > </ span > < span class ="n "> n</ span > < span class =" w " > </ span > < span class ="o "> <<</ span > < span class =" w " > </ span > < span class ="n "> < a href ="../../reference/ostream/endl.html "> std::endl</ a > </ span > < span class ="p "> ;</ span >
253253< span class ="p "> }</ span >
254254</ code > </ pre > </ div >
255255</ p >
0 commit comments