よくあるクラス内でメソッド名は同じなんだけど引数が違うメソッド(用語忘れた オーバーロード)で、引数にboolとstd::stringを使った際にハマった際の対処
@OTL さんに助けてもらった。ありがとうございます!
https://twitter.com/OTL/status/669676415877406724
クラス内でメソッド名は同じなんだけど引数が違うメソッドが「オーバーロード」っていうことを 紫さん に教えてもらった。
問題
以下のコードを実行した際に string が出力されて欲しいところが、 bool が出力される。
class hoge {
public:
void m(bool value) {
std::cout << "bool";
}
void m(std::string value) {
std::cout << "string";
}
}
void main() {
hoge h;
h.m("str"); // <- bool が出力される
}
原因
文字列として "" を使っているが、実際は char *型 なので、ポインタ。
ポインタは std::string型 よりも bool型 に優先されて変換されるため、bool が出力される。
http://stackoverflow.com/questions/14770252/string-literal-matches-bool-overload-instead-of-stdstring
対処
呼び出し側でキャスト
classの実装が変えられない時とかに対処する場合とか。
呼び出し側で std::string型 にキャストしてしまう。
void main() {
hoge h;
h.m(std::string("str")); // <- string が出力される
}
実装の修正
char *型 の引数を受けるメソッドを用意してしまう。
class hoge {
public:
void m(bool value) {
std::cout << "bool";
}
void m(char* value) {
std::cout << "char*";
// m(std::string(value)); // こちらでも可
}
void m(std::string value) {
std::cout << "string";
}
}
void main() {
hoge h;
h.m("str");
}
雑感
javaとかpythonやってるとc++の文字列がポインタだということを忘れてしまう。