これは、より多くのポリシーまたは歴史的な質問です。std::stringにconstchar*変換を提供しないことが決定されたのはなぜですか?誰かがprintf( "%s"、s)を実行し、それが自動的に変換されると信じる恐れはありましたか?この問題についてオープンな議論はありますか?
4 に答える
自動キャストはほとんど常に悪です。へのキャストがあった場合const char *
、 astd::string
は他のポインター型にも自動的にキャストされる可能性があり、それが見つけにくいバグにつながる可能性があります。c_str()
返されるメソッドがあるためconst char *
、必要なものを引き続き実現できます。また、型キャストは論理的に正しくstd::string
ありません - と同等ではありませんconst char *
。
文字列クラスは内部的に文字列を 0 で終了する必要はありません。したがって、コストのかかる操作になる可能性があるため、暗黙のキャストは意味がありません。
c_str() 関数は、c-string を提供します。ライブラリが内部に保存する方法によっては、この関数は一時的なものを作成する必要がある場合があります。この一時的なものは、文字列を変更するまでのみ有効です。
残念ながら、文字列は内部的に c-string として指定されている可能性があるためです。これにより機能が失われることはなく、暗黙的な変換が可能になります。
編集標準は基本的に、メモリが連続していることを意味します (data() または [] 演算子を介してアクセスする場合)。おそらくすべての実装で 0 も格納されます。これが標準化されていれば、暗黙の変換を安全に定義できます。
以前のコメントについて:
それらが同等である場合、c_str() 呼び出しの代わりにキャストを使用することに (利便性を除いて) 違いはありません。
非常に重要な違いが 1 つあります。1 つは暗黙的で、もう 1 つは明示的です。
C++0x ではキャスト演算子の概念が導入されていますexplicit
が、それまではキャスト演算子は暗黙的であり、(コードを見たときに) 使用されるかどうかが明確ではありません。
特にカスケードできるため、暗黙のキャストは良くなく、コードが非常にわかりにくくなります。
さらに、すでに述べたように、ここには正確性の問題があります。によって返されるポインターはc_str
、オブジェクトが変更されない限り有効であるため、string
見つけにくいバグに遭遇する可能性があります。検討:
void function()
{
std::map<int, char const*> map;
map[1] = boost::lexical_cast<std::string>(47);
std::cout << map[1] << std::endl; // CRASH here, if lucky...
}
私の感じでは、C ++は強く型付けされた言語であり、暗黙の型変換は型の安全性を損ないます。
多くの場合、予期しないポイントで変換が発生し、コードのデバッグが困難になる可能性があります。
非明示的コンストラクターも同様の効果をもたらす可能性があり、std::string自体にはconstchar*からの暗黙的コンストラクターがあります。この場合、コードが非効率になる可能性はありますが、必ずしも悪いことではありません。