2012-02-19 7 views
4
void callme(string a) 
{ 
    cout<<"STRING CALLED"<<endl; 
} 

void callme(char * a) 
{ 
    cout<<"char pointer called"<<endl; 
} 

int main() 
{ 
    callme("ASDADS"); 
    return 0; 
} 

なぜchar*が呼び出されるのですか?なぜchar*パラメータで関数をコメントアウトすると、代わりに他の関数が呼び出されるのでしょうか?C++関数パラメータのcharポインタと文字列

+1

(コードには、コードブロックを選択して '{} 'ボタンをクリックするか、Ctrl + Kキーを押してください) – Mat

答えて

0

あなたが両方の機能を持っているときは、( "*")から選択する2つの選択肢が引数 "ASDADS"に適しています。 (char *)関数を削除すると、文字列を必要とする単一の関数が存在します。したがって、コンパイラはchar *を取る文字列コンストラクタを使用して文字列を作成します。 "ASDADS"char *に変換可能であるためだ

http://www.cplusplus.com/reference/string/string/string/

4

。コンパイラは、引数と一致する最初の関数のコードを生成します。

char *でプロトタイプを削除すると、コンパイラは、char *からパラメータ型への暗黙的キャストを持つパラメータを受け入れる関数を探します。

例えば次のように乗り:

class A 
{ 
public: 
    A() {} 
    A(int x) {} 
}; 

//void foo(int x) {} 
void foo(A x) {} 

int main(int argc, char* argv[]) 
{ 
    int x = 3; 
    foo(x); 
} 

あなたがfoo(int x)をコメントアウトした場合、他の関数が呼び出されます。

class A 
{ 
public: 
    A() {} 
    explicit A(int x) {} 
}; 
3

文字列リテラルのタイプ(​​のような)「のconst charの配列」は次のとおりです。あなたはexplicitとしてコンストラクタを宣言した場合

しかし、あなたはエラーを取得します。しかし、特別なルールとして、C++では、(非推奨!)標準変換をchar *にすることができます。このような変換は、コンストラクタstring::string(const char *)によって提供されるユーザ定義の変換よりも優先されます。したがって、オーバーロード解決中にchar*のオーバーロードが優先されます(stringの1つのユーザー定義変換ではなく、char*のユーザー定義変換はゼロです)。

(私は実際にこのための標準的な参照を見つけることができません。逆に、C.1.1はそれ以上の入力が高く評価されchar * p = "abc";は「C++で無効」であることを明示的に言う編集:。。これがあるように思えC++ 03からC++ 11への変更、およびC++ 11での変更は実際には完全に違法です。)

+0

これはコンパイラの拡張機能だと思います。私は本当にそれを実際に持っていることはありません。なぜ、あなたは 'char * =" foo ";'を持つことが許されているのですか?それを変更しようとするとUBに入ります。なぜそれが 'const char *'であることを強制するのではないのですか? –

+0

@LuchianGrigore:GCCの '-pedantic'を使っても、"廃止予定の変換 "と言われているので、拡張のようには聞こえません。 –

+0

私はMSVS2008について話していました。私は警告をもらっていません。 –

0

デフォルトでは、 "ASDADS"はcharポインタによって参照されます。したがってcallme()の第2版が使用されます。これがコメントされている場合、コンパイラはそれをstringとマッチさせようとします。したがって、callme()の第1版が使用されます。

関連する問題