私はGoogleC ++スタイルガイドを調べていましたが、これに出くわしました。
「名前空間stdで何も宣言しないでください。標準ライブラリクラスの前方宣言も含めないでください。名前空間stdでエンティティを宣言することは未定義の動作です。つまり、移植性はありません。標準ライブラリからエンティティを宣言するには、適切なヘッダーファイルを含めます。」
誰かがこれが何を意味するのか、そしてなぜこれが未定義の振る舞いであるのかをサンプルコードを使って説明できますか?
私はGoogleC ++スタイルガイドを調べていましたが、これに出くわしました。
「名前空間stdで何も宣言しないでください。標準ライブラリクラスの前方宣言も含めないでください。名前空間stdでエンティティを宣言することは未定義の動作です。つまり、移植性はありません。標準ライブラリからエンティティを宣言するには、適切なヘッダーファイルを含めます。」
誰かがこれが何を意味するのか、そしてなぜこれが未定義の振る舞いであるのかをサンプルコードを使って説明できますか?
誰かがこれが何を意味するのか、そしてなぜこれが未定義の振る舞いであるのかをサンプルコードを使って説明できますか?
次のプログラムでは、未定義の動作が発生します。
namespace std {
void foo(int) { }
}
#include <iostream>
int main() {
std::cout << "Hello World!" << std::endl;
}
なんで?foo
名前空間で指定された関数を宣言しますstd
。これが問題を引き起こす可能性がある理由については、次のことを考慮してください。標準ライブラリの実装には、という名前の独自の関数があり、のfoo()
一部のコンポーネントで使用される場合があります<iostream>
。foo
その場合、標準ライブラリの実装よりも適切に一致する可能性がありますfoo
。
まず第一に、Googleスタイルガイドの多くのように、それは実際には間違っています。この標準では、名前空間stdでいくつかの特定のエンティティを定義できます(たとえば、ユーザー定義タイプに対する既存のテンプレートの特殊化)。
ただし、これらの例外を無視すると、正しい一般的な考え方があります。通常、コードは名前空間std以外の場所に属します。グローバル名前空間に配置することも、別の名前空間を定義することもできますが、そのままにしておく必要がありますstd
。
また、標準ライブラリで何かを前方宣言しようとしないでください。標準関数は、デフォルト値が含まれている限り、(たとえば)追加のパラメーターを含めることができるため、標準的な方法で呼び出すことができます。既存の関数を宣言する代わりに、自分で宣言しようとすると、代わりにあいまいなオーバーロードを宣言してしまう可能性があります。
結論:はい、標準ライブラリを使用します。使用する場合は、独自のヘッダーを作成するのではなく、標準ヘッダーを含めて宣言を取得してください。
std
これは、名前空間で独自の型を宣言しないことを意味します。標準ライブラリを使用できますが、適切なヘッダーを含めることによって使用する必要があります。
基本的に、すべての宣言がではなく、独自の名前空間にあることを確認してくださいstd
。
彼らはあなたがこのような標準ライブラリからのものを前方宣言するべきではないと言っています:
// myheader.h
namespace std{
template<class T>
void SomeStandardFunction();
}
// use std::SomeStandardFunction
代わりに、ヘッダーを直接含める必要があります。
// myheader.h
#include <SomeHeaderThatContainsSomeStandardFunction>
// use std::SomeStandardFunction
これは「標準ライブラリを使用しない」という意味ではありません。
何かを使用することと、何かを宣言することは、2つの異なることです。「classostream;」のようなことをしないように、何も宣言しないでください。以前はそのように宣言しなければならなかったと思いますが、今では名前空間stdで宣言されているので、ヘッダーファイルをインクルードするだけです。
これをチェックしてください。