ソース コードは、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 構文のキャストを回避するため、正規表現やその他のパターン マッチングを介して検索する際の誤検出を回避できます。
しかし、なぜ!!
(否定演算子の二重適用) なのか? からへの自動暗黙的な変換があることを考慮すると? そして、変換が明示的であるべきだと絶対に感じているなら、それは であるべきではなく、ではないでしょうか?int
bool
static_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 に感謝します。