7

これを実際のコードで使用するつもりはありません。約束します。

標準では、関数の引数が型であり、組み込み型ではないstd場合に名前空間が見つかることが保証されていますか?container::iteratorcontainer::iteratortypedef

例えば

#include <set>
#include <algorithm>
int main()
{
   std::set<int> s;
   find(s.begin(), s.end(), 0); //do I have a guarantee that std::find will be found?
}

言い換えると、イテレータクラスはstd、ADLで考慮されないような名前空間で定義できますか?

前もって感謝します。

4

2 に答える 2

5

::iterator標準コンテナの正確なタイプなどは実装定義であるため、理論的には、それがtypedef外部の何かstd::(たとえば、プレーンポインタ)になるのを妨げるものは何もありません。

この場合、ADLが常に機能することを示唆する基準は他にありません。したがって、誰かが私を訂正しない限り、答えは次のようになります。いいえ、想定することはできません。それfindはADLを介して見つかります。

于 2011-07-23T22:09:09.377 に答える
5

最も一般的なケースでは答えはノーだと思いますが、ほとんどの実用的な実装ではイエスです。

C ++ISO標準§3.4.2/2によると、引数には「関連付けられた名前空間」の概念があり、これは次のような方法で定義されます。

Tがクラスタイプ(ユニオンを含む)の場合、関連するクラスは次のとおりです。クラス自体。メンバーであるクラス(ある場合)。およびその直接および間接の基本クラス。関連する名前空間は、関連するクラスが定義されている名前空間です。

これは、イテレータ型が実際にのようなコンテナ内のネストされた型である場合、は関連付けられたクラスであり、を含む名前空間std::setであるため、の呼び出しでそのイテレータに関連付けられた名前空間は、にfindなることを示しています。次に、規格は次のように述べています(§3.4.2/ 2a)stdstd::setstdset

名前の通常の非修飾ルックアップでクラスメンバー関数の宣言が見つかった場合、関連する名前空間とクラスは考慮されません。それ以外の場合、関数名のルックアップによって検出された宣言のセットは、通常の非修飾ルックアップを使用して検出された宣言のセットと、引数タイプに関連付けられた名前空間およびクラスで検出された宣言のセットの和集合です

findこれは、実際に関数がで見つかることを意味しますnamespace std

ただし、これが一般的に機能することは保証されていません。また、仕様(§3.4.2)から次のことがわかります。

タイプを指定するために使用されるTypedef名とusing-declarationsは、このセットには寄与しません。

したがって、質問で述べたように、イテレータタイプがある種のtypedef場合、これが正しく機能することは保証されません。しかし、それを除けば、型がtypedefでないことがわかっている場合はnamespace std、のクラスにあるかネストされているnamespace std必要があり、ADL用に取得する必要があるようです。 しかし、それをしないでください!:-)

于 2011-07-23T22:11:02.350 に答える