7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

引数にboolとstd::stringを取るオーバーロードがあると"str"はboolにとられる

7
Last updated at Posted at 2015-11-26

よくあるクラス内でメソッド名は同じなんだけど引数が違うメソッド(用語忘れた オーバーロード)で、引数に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++の文字列がポインタだということを忘れてしまう。

7
6
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?