2009-07-19 3 views
14

引用符で囲まれた文字列がboolメソッドのシグネチャとstd :: stringの前に一致するのはなぜですか?

// Method 1 
void add(const std::string& header, bool replace); 

//Method 2 
void add(const std::string& name, const std::string& value); 

次のコードは、方法2の代わりにメソッド1を呼び出すことになります。

something.add("Hello", "World"); 

次のような別のメソッドを作成しました。

//Method 3 
void MyClass::add(const char* name, const char* value) { 
    add(std::string(name), std::string(value)); 
} 

それは働いた。したがって、メソッドが "引用符付き文字列"を受け入れると、次の順序で一致します。

  1. const char*
  2. bool
  3. std::string

引用符で囲まれた文字列を扱う理由std::stringの前にboolとして?これは通常の行動ですか?私はこのプロジェクトのためのまともな量のコードを書いており、間違ったメソッドの署名が選択されていることで他に何の問題もなかった...

答えて

14

私の推測では、ブール値へのポインタからの変換である暗黙のプリミティブ型変換、である...このプロジェクトのためのコードのまともな金額を書かれているし、選択されている間違ったメソッドのシグネチャを持つ任意の他の問題がありませんでしたstd::stringに変換するには、コンストラクタの呼び出しと一時的な構造の構築が必要です。

+2

これはそれです。私は一度この問題があり、それは私を混乱させましたが、2番目のパラメータはconst char *であり、それはブール値に変換されます。 – GManNickG

6

ポインタはboolへの暗黙的な変換を持っています。おそらく、あなたは次のことを見てきました。今

void myFunc(int* a) 
{ 
    if (a) 
     ++(*a); 
} 

、C++で、組み込み型間の暗黙的な変換は、クラスの型の間の変換よりも優先されます。あなたはクラスの持っていたのであれば、たとえば、:

class Int 
{ 
public: 
    Int(int i) {} 
} 

をそして、あなたはlongIntのための機能を、オーバーロード:

void test(long n) {cout << "long";} 
void test(Int n) {cout << "Int";} 

次のコードは、長いオーバーロードを呼び出すことがわかりますあなたが持っているあなたの場合

int i; 
test(i); 
+0

標準によって定義されているにもかかわらず、std :: stringも「ユーザー定義」であることに注意してください。より適切な用語は「クラス型」対「非クラス型」です。 – MSalters

+0

良い点。編集されました。 – rlbond

9

は、オーバーロードされた機能を持っています。オーバーロードの分解能は、13.3項に従って発生します。

C++ 03 13.3.3.2/2:

(13.3.3.1で定義されるように)暗黙的な変換シーケンスの基本的な形態を比較
- 標準変換シーケンス(13.3.3.1ユーザ定義の変換シーケンス(13.3.3.1.2)は、省略記号の変換シーケンス(13.3(1))よりも優れた変換シーケンスです。ユーザ定義の変換シーケンス(13.3.3.1.2)は、ユーザ定義の変換シーケンスまたは省略記号の変換シーケンスよりも優れた変換シーケンスであり、
.3.1.3)。

ブール値に変換ポインタは、標準的な変換です。 std :: stringへの変換ポインタは、ユーザ定義の変換です。

4.12ブール変換 メンバー型に算術、列挙の右辺値、ポインタ、またはポインタは、タイプBOOLの右辺値に変換することができます。ゼロ値、ヌルポインタ値、またはヌルメンバポインタ値はfalseに変換されます。他の値はすべてtrueに変換されます。

関連する問題