11

次のようなコードがある場合

class CString { int GetLength(); };

bool smaller(CString s1, std::string s2) {
    return s2.size() > s1.GetLength();
}

私にとって最善のことは何ですか?

  • ?s1.GetLength()に変更 これは、「符号付きと符号なしの不一致」に関するコンパイラの警告を取り除き、キャストする意図を伝えるのに役立ち、はるかに簡単な方法です。しかし、それはおそらく眉をひそめています。:((size_t)c.GetLength()

  • ?s1.GetLength()に変更 これは、「正しい」種類のキャストを使用して、警告を取り除くのに役立ちます。static_cast<size_t>(c.GetLength())

  • ?s1.GetLength()に変更 非常に冗長です...この抽象化には実際的な利点がありますか、それとも破るべきですか?static_cast<std::string::size_type>(c.GetLength())

  • そのまま?これは、警告を犠牲にして、コンパイラがスイッチ
    を使用してオーバーフローチェックを行うのに役立ちます(ここでの私の主な関心事)。/RTCc

  • 何か他のことをしますか?
    独自のキャスト関数を作成する必要がありますか? マクロを使用しますか?コンパイル時だけでなく実行時もチェックする必要がありますか? 他のアイデアはありますか?

編集:

例が少し文字通りに取られすぎているようです...

私は明らかにについて話すつもりはありCString::GetLength()ませんでした。その特定の方法は、確かに私の大きな心配ではありません。:) 私が心配しているのは、より一般的なケースです。負になることは決してないはずですが、理論的にはバグのために負になる可能性がある整数を取得する場合です。

別のコードをオーバーライドするために、これを行うメソッドを作成している可能性があります。そのため、署名を変更することはできません。また、予想していなかったとしても、私のコードには確かにバグが含まれている可能性があります。

このような場合、どうすればよいですか?

4

4 に答える 4

6

変更できますGetLength()か?基本的に、問題は長さが負になることはなく、符号なしの型がそれを最もよく反映しているということです。長さは で測定しないでくださいint

しかし、それ以外は、3 つのソリューションはすべて同じです。std::string::size_typeは常にstd::size_tであり、私は a を使用しますがstatic_cast、この場合、C スタイルのキャストは同じキャストを実行します。返される長さが負になることは決してないことがわかっているため (ちなみに、これを確認してください。人々が何をする可能性があるかは決してわかりません)、型をキャストするだけで完全に安全です。

return s2.size() > static_cast<std::size_t>(s1.GetLength());

何らかの理由で負になるCString::GetLength 可能性がある場合、その負から正への変換を行う方法を決定するのはあなた次第です。切り捨てますか?等級(絶対値)?あなたに必要なものは何でも。


バグが心配な場合は、明示的なチェックを行って例外をスローする (ドメインによっては、コストがかかりすぎる場合があります) か、assert. ただし、一般的には、ドキュメントを信頼する必要があります。

于 2012-04-05T08:58:11.747 に答える
4

コメントを付けて、キャストを独自の関数に入れます。

std::string::size_type size(const CString& mfcString)
{
    // CString::GetLength is always non-negative
    // http://msdn.microsoft.com/en-us/library/aa300471(v=vs.60).aspx

    return static_cast<std::string::size_type>(mfcString.GetLength());
}

次に、コードは次のようになります。

bool smaller(const CString& s1, const std::string& s2)
{
    return size(s1) < s2.size();
}
于 2012-04-05T09:18:08.470 に答える
2

CString::getLength()適切な解決策は、署名を変更して署名なしの型を返すことだと思います。CString引数を値で取得する場合は、 を取得するための変換コンストラクターを提供することを検討することをお勧めしstd::stringます (または、関数のシグネチャを で引数を取得するように変更する必要がありますconst&)。

個人的には、操作をキャストではなく変換と見なし、次のように記述します。

return std::string::size_type(s1.getLength())
    < s2.size();
于 2012-04-05T09:06:41.100 に答える
0

メソッドCString::getLength()を変更し、符号なしの型を返します。

これを試して

std :: string :: size_type(s1.getLength())<s2.size();を返します。

于 2012-04-05T11:33:10.223 に答える