2016-12-17 14 views
1

標準のalgorithmヘッダーのいくつかのアルゴリズムはstd::を必要としないという事実を知りました。find_if、for_each、countなどにstd ::が不要な理由はありますか?

例:

#include <vector> 
#include <algorithm> 

int main() { 
    std::vector<int> m; 
    count(m.begin(), m.end(), 0); 
    count_if(m.begin(), m.end(), [](auto){return true;}); 
    for_each(m.begin(), m.end(), [](auto){}); 
    find_if(m.begin(), m.end(), [](auto){return true;}); 
} 

Live demo at coliru

は、そのための具体的な理由はありますか? g++clang++はどちらも上記のコードを受け入れます。

+5

ADLのため、リファクタリングしてカスタムコンテナを使用する場合には、それに頼らないことをお勧めします。 –

+0

https://en.wikipedia.org/wiki/Argument-dependent_name_lookup –

答えて

6

ここでは2つのことが起こっています。

最初はADLまたはArgument Dependent Name Lookupです。

機能はADLを介して検出されています。これは、いくつかの引数(vectorのタイプiteratorのタイプ)がstdにあるため、オーバーロードの解像度がfor_eachの場合、通常の名前空間(この場合はroot)のセットとその引数の名前空間。

トリックはvector::iteratorですnamespace stdのタイプであることが保証されていません。したがって、あなたのコードは動作保証されていません。 stdの型であるか、未加工のポインタであるか、namespace __std__utility_typesなどの型である可能性があります。

すべての主要なコンパイラライブラリでは、ポインタはポインタではなく、vectorイテレータはありません。これは、代替として悪いと見なされるため、namespace stdにあります。しかし、保証の欠如は、本当に移植可能なコードではそれに頼るべきではないということです。

+0

私は、MicrosoftのIDEがADL(「編集者アシスタント」IntelliSense)を介してこれらの機能を「発見」していたが、コンパイル時コンパイラADLの使用に失敗しました。 – Swift

関連する問題