2

私は、c 文字列 (char*) と c++ 文字列 (std::string) の両方を処理することになっているプログラムを作成しています。以下の例に関心を持って分離しました。

#include <iostream>
#include <string>

void hello(std::string s) {
    std::cout << "STRING FUNCTION" << std::endl;
}

void hello(char* c) {
    std::cout << "CHAR FUNCTION" << std::endl;
}

int main(int argc, char* argv[]) {
    hello("ambiguous");
    hello((std::string)"string");
    hello((char*)"charp");

    return 0;
}

このプログラムをコンパイルすると、次の警告が表示されます。

test.cpp:14: warning: deprecated conversion from string constant to ‘char*’

への最初の呼び出しに関してhello。プログラムを実行すると、次のようになります。

CHAR FUNCTION
STRING FUNCTION
CHAR FUNCTION

への最初の呼び出しがhello署名と一致していることを示していますhello(char* c)

私の質問は、C++ プログラムとして、文字列リテラル ( ) が std::string である場合、なぜstd::string のままでマッチングするのではなく"ambiguous"、a にキャストされてからchar*関数に一致するのでしょうか?hello(char* c)hello(std::string s)

警告をプラグマ化または -Wsomething できることはわかっています (そして、心配することなく char* を文字列にキャストできます) が、なぜコンパイラがわざわざこのキャストを行うのか、またそうしないように指示する方法があるかどうかを知りたいです。 . g++ 4.4.3 でコンパイルしています。

ありがとうございました。

4

3 に答える 3

5

のような文字列リテラル"ambiguous"は型ではありませんstd::stringstd::stringはライブラリのみのタイプであり、言語の魔法はまったくありません。文字列リテラルのタイプは実際const char[N]にはです。ここNで、はリテラルの長さです。

歴史的な理由(下位互換性)のために、文字列リテラルは暗黙的にchar*(const-correctnessに違反して)変換されます。この組み込みの変換は、への「ユーザー定義」変換よりも優先されます。std::stringそのため、関数が呼び出されchar*、警告が表示されます。

の署名をに変更しhellohello(const char* c)も、おそらくもう警告は表示されません(ただし、std::stringバージョンを呼び出さないため、手動でキャストする必要があります)。

于 2013-03-20T22:22:15.693 に答える
0

("あいまい")はstd :: stringではなく、文字の配列です。

そのため、void hello(char * c)を呼び出します。

于 2013-03-20T22:22:15.977 に答える
0

あなたは間違っています:「C++プログラムとして、文字列リテラル(「あいまい」)はstd::stringです」

于 2013-03-20T22:14:32.257 に答える