2016-04-04 18 views
9

これは正常にコンパイルできますか?なぜstd :: generateは名前空間修飾子なしでアクセスできますか?

#include <vector> 
#include <algorithm> 

int main() 
{ 
    std::vector<int> buf; 
    generate(buf.begin(), buf.end(), []{ return 0; }); 
} 

generate()の前に行方不明std::注)

はどこかに文書化され、この動作ですか?あるいは、私はコンパイラやライブラリのバグに遭遇しましたか?私の場合、GCC 5.3.0とLinuxのClang 3.8.0でしょうか。どちらもlibstdC++を使用しているので、おそらくライブラリのバグですか?

+5

[引数依存ルックアップ](https://en.wikipedia.org/wiki/Argument-dependent_name_lookup)多分? – zwol

+0

AFAIK - 同じ名前空間( 'std')内に' std :: vector'型が定義されているので、これは受け入れられます。 – soon

+6

@soon:iterator型が名前空間 'std'に存在するかどうかは不明です。イテレータの型が裸のポインタの場合、それは動作しません。特に、デバッグモードまたは最適化モードでコンパイルするかどうかによって動作が異なる場合があります。 –

答えて

3

これは、実質的にgenerateの引数がstdにあるためです。

namespace Foo 
{ 
    struct B{}; 
    void foo(const B&); 
} 

int main() 
{ 
    Foo::B b; /*Requires Foo::*/ 
    foo(b); /*Does not require Foo:: as that is gleaned from the argument*/ 
} 

コードは、同様の理由で許容されます。 引数に依存する参照と呼びます。 https://en.wikipedia.org/wiki/Argument-dependent_name_lookup

+7

引数(ベクトルイテレータ)が 'namespace std'にあることは保証されていません。したがって、これはいくつかのプラットフォーム/構成ではコンパイルに失敗する可能性があります。 – interjay

+2

'generate(x、y、f);を呼び出すと、すべての引数型の名前空間が' generate'という名前で検索されます。関数名の検索が始まる前に引数から名前空間が取り出されます。 –

関連する問題