暗黙の型変換のトラブル

暗黙の型変換は便利ですが、ちょっと理解が足りないと原因特定がめんどうな困ったチャンです。

#include <iostream>
#include <string>

void function(const bool arg){
    std::cout << "boolean: " << arg << std::endl;
}

void function(const std::string &arg){
    std::cout << "string: " << arg << std::endl;
}

int main(){
    function(true); //  function(const bool)が呼ばれる
    function(std::string("aaa")); //  function(const std::string &)が呼ばれる
    function("bbb"); //  どっち?
}

boolean: 1
string: aaa
boolean: 1


const char *がNULLであればfalse(0), それ以外でtrue(1)として受け取ってしまうらしい。
std::stringのコンストラクタにconst char *を渡してもインスタンスが生成できるので、その変換を期待した結果がこれだよ!!
出来れば3つ目の"bbb"は文字列(std::string)として変換してもらいたい。
std::string("bbb")とでもすればいいんだけど、呼び出す度にそれではタイプ量が増えるので、それ以外の解決方法。


一つ関数をオーバーロードしてやる事で解決できる。

void function(const char * arg){
    function(std::string(arg)); // 処理はfunction(const std::string &)に任せる
}

文字列定数"aaa"や"bbb"はconst char *として扱えるので、
const char *を引数にとる同名の関数でオーバーロードしてやれば、そちらを最初に呼び出してくれる。
で、内部でstd::stringで明示的に変換させてやって、処理はstd::stringを引数にしたときと同じ処理にする。
いちいちstd::string("bbb")とするよりラクチンですね。


暗黙の型変換の順序は 組み込み型>ユーザ定義クラス という感じなのかな。細かい仕様はわからん・・・
まぁ、boolかstd::stringを引数にとる同名の関数ってあまり無いような気もしますが:P