ベクトル クラスを使用する場合は名前空間指定子を記述しなければならないstd::vector
のに、std::find
関数の場合は省略できるのはstd::
なぜですか? 違いはなんですか?どちらもstd
名前空間で定義されていますよね?
4 に答える
ベクトルクラスを使用するために名前空間指定子 std::vector を記述する必要があるのに、 std::find 関数では std:: を省略できるのはなぜですか?
一般的に、それは真実ではありません。
違いはなんですか。どちらも std 名前空間で定義されていますよね?
はい、原則として違いはありません。C++11 標準のパラグラフ 17.6.1.1/2 によると:
マクロ、演算子 new および演算子削除を除くすべてのライブラリ エンティティは、名前空間
std
または名前空間内にネストされた名前空間内で定義されますstd
。[...]
ただし、 Argument-Dependent Lookupのルールによって例外が許可されていることに注意する必要があります。この検索手法のおかげで、名前は関数の名前空間で検索されるため、関数の名前空間を明示的に指定する必要はありません。その関数に提供する引数。
したがって、関数がたまたまその引数のいずれかと同じ名前空間で定義されている場合、その名前がそれが属する名前空間で修飾されていなくても、コンパイラによって検出されます。
namespace N
{
struct X { };
void foo(X) { }
}
int main()
{
N::X x;
foo(x); // OK
}
したがって、名前空間でstd::find()
定義された型のインスタンスであるいくつかの引数を使用して呼び出す場合、 withstd
への呼び出しを修飾する必要はありません。例えば:find()
std::
#include <vector>
#include <algorithm>
#include <iostream>
int main()
{
std::vector<int> v { 1, 2, 3 };
auto i = find(v.begin(), v.end(), 2); // ADL applies if the result of
// v.begin() and v.end() is an
// iterator whose type is defined
// in the std namespace!
std::cout << *i;
}
明らかに、これは引数を受け入れない関数には適用できません。その場合、もちろん呼び出しポイントがその名前空間内にある場合を除き、名前空間修飾は常に必要です (名前空間に何も追加することはできませんが、std
名前空間の一部のテンプレートはstd
特殊化できます)。
最初に、プログラムにライブラリを含めます (std 名前空間)。その後は、常に std という単語を使用する必要はありません。しかし実際には、すべてのオブジェクトが std::cout std::cin と等しい
std は C++ の基本ライブラリの 1 つです。
呼び出し方法によって異なりますstd::find
...たとえば、 std コンテナーからいくつかの反復子を渡す場合、この関数はADLstd::
によって検出されます。それ以外の場合は、呼び出すために追加する必要があります。
何らかの理由で、STL はグローバル名前空間で多くのアルゴリズム ( ) を公開することを選択しました。そのため、find(...) または transform(...) と書くことができます。ベクトルは公開されていないため、公開する必要がありますstd::vector<>()
。またはstd::vector;
、ファイルの先頭に using を配置することもできます