ソース コードは、Visual C++ 11.0 (Visual Studio 2012 に同梱されているコンパイラ) で警告なしにコンパイルされます。
Intellisense は独自のルールを使用するため、常に信頼できるとは限りません。
そうは言っても、オリジナルの 7 ビット ASCII を除くすべての文字セットでの使用isspaceは未定義の動作です。つまり、あなたがそれを選んだ非常に支持された答えは、ただのばかげたものです(驚くべきことではありません)。負の値と UB を避けるために、引数を (C ライブラリの)isspaceにキャストする必要があります。unsigned char
C99 §7.4/1 (N869 ドラフトから):
ヘッダー<ctype.h>は、文字のテストとマッピングに役立ついくつかの関数を宣言します。すべての場合において、引数は でありint、その値は として表現可能であるunsigned charか、マクロの値と等しくなければなりませんEOF。引数が他の値を持つ場合、動作は未定義です。
C 関数をラップする簡単な方法は次のとおりです。
bool isSpace( char const c )
{
typedef unsigned char UChar;
return !!::isspace( UChar( c ) );
}
なぜtypedefですか?
そのような が既にある場合、コードを簡単に適応させることができますがtypedef、これは珍しいことではありません。
コードがより明確になります。と
C 構文のキャストを回避するため、正規表現やその他のパターン マッチングを介して検索する際の誤検出を回避できます。
しかし、なぜ!!(否定演算子の二重適用) なのか? からへの自動暗黙的な変換があることを考慮すると? そして、変換が明示的であるべきだと絶対に感じているなら、それは であるべきではなく、ではないでしょうか?intboolstatic_cast!!
!! Visual C++ コンパイラからのばかげた警告を回避します。
「警告 C4800: 'int': 値を bool 'true' または 'false' に強制しています (パフォーマンス警告)」
そして、static_castその警告を止めません。Visual C++ は最もよく使用されるシステム、つまり Windows のメインの C++ コンパイラであるため、移植性を意図したすべてのコードでこれを行うことをお勧めします。
オーケー、でも、とにかく関数をラップしなければならないので…ヘッダーがはるかに柔軟な C++ (2 つの引数)関数を提供しているのに、なぜ古い C ライブラリisspace(単一引数) 関数を使用するのでしょうか?<locale>isspace
何よりもまず、古い Cisspace関数が質問で使用されているため、この回答で説明されている関数です。これを誤って行わない方法、つまり、未定義の動作を回避する方法に焦点を当ててきました。それを正しく行う方法について話し合うことは、それをまったく異なるレベルに引き上げます。
しかし、実際には、同じ名前の C++ レベル関数は壊れていると見なすことができます。これは、g++ コンパイラでは最近まで (そしておそらく g++ 4.7.2 でも最近チェックしていません)、C ロケール メカニズムのみであったためです。 Windowsでは機能しましたが、C++レベルのものは機能しませんでした. g++ がワイド ストリームをサポートするようになったため、修正された可能性がありますが、わかりません。とにかく、C ライブラリisspace関数は、より移植性が高く、一般的に Windows で動作することに加えて、より単純で、より効率的であると私は信じています(ただし、効率のために、重要と見なされる場合は常に測定する必要があります!)。
コメントで上記の質問を (本質的に) 行ってくれた James Kanze に感謝します。