[解決済み] const std::string& を受け取る関数が 0 を受け取らないようにする。
質問
千の言葉に匹敵する。
#include<string>
#include<iostream>
class SayWhat {
public:
SayWhat& operator[](const std::string& s) {
std::cout << s << "\n";
return *this;
}
};
int main() {
SayWhat ohNo;
// ohNo[1]; // Does not compile. Logic prevails.
ohNo[0]; // you didn't! this compiles.
return 0;
}
文字列を受け入れるブラケット演算子に数値0を渡しても、コンパイラは文句を言いません。その代わり、これはコンパイルされ、withメソッドへのエントリーの前に失敗します。
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
参考までに
> g++ -std=c++17 -O3 -Wall -Werror -pedantic test.cpp -o test && ./test
> g++ --version
gcc version 7.3.1 20180303 (Red Hat 7.3.1-5) (GCC)
私の推測
コンパイラは暗黙のうちに
std::string(0)
コンストラクタを使用してメソッドに入るため、正当な理由なく同じ問題 (上記のエラーでググってみてください) が発生します。
質問
APIユーザがこれを感じず、コンパイル時にエラーが検出されるように、クラス側でこれを修正する方法はありますか?
つまり、オーバーロードを追加する
void operator[](size_t t) {
throw std::runtime_error("don't");
}
は良い解決策ではありません。
どのように解決するのですか?
原因
std::string(0)
が有効である理由は
0
がヌルポインタ定数であるためです。つまり、0は文字列コンストラクタがポインタを取ることにマッチします。すると、このコードは、NULLポインタを
std::string
.
リテラルのみ
0
の中の実行時値であれば、ヌルポインタ定数として解釈されます。
int
の実行時値であれば、この問題は発生しません(オーバーロードの解決は
int
の変換を探すことになるため)。また、リテラル
1
は問題ではありません。
1
はヌルポインタ定数ではないためです。
これはコンパイル時の問題(リテラルが無効な値)なので、コンパイル時にキャッチすることができます。このフォームのオーバーロードを追加してください。
void operator[](std::nullptr_t) = delete;
std::nullptr_t
のタイプは
nullptr
. そして、それは
にもマッチします。
ヌルポインタ定数、それが
0
,
0ULL
または
nullptr
. そして、この関数は削除されているので、オーバーロードの解決時にコンパイルタイムエラーを引き起こします。
関連
-
[解決済み] テスト
-
[解決済み】C++の変数はイニシャライザーを持っているが、不完全な型?
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み] std::string を const char* または char* に変換する方法
-
[解決済み] ファイルの内容からJavaの文字列を作成するにはどうすればよいですか?
-
[解決済み] 文字列から空白を取り除くには?
-
[解決済み] IList<string> または IEnumerable<string> からカンマ区切りリストを作成する。
-
[解決済み] std::stringのインスタンスを小文字に変換する方法
-
[解決済み] const std::string & をパラメータとして渡す時代は終わったのでしょうか?
-
[解決済み] std::stringをintに変換するにはどうしたらいいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】coutはstdのメンバではない
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み】std::cin.getline( ) vs. std::cin
-
[解決済み】string_viewとは何ですか?