web-dev-qa-db-ja.com

C ++でchar *をconstchar *に変換します

変換方法char*からconst char* C++では?プログラム1は機能しているのに、プログラム2は機能しないのはなぜですか?

Prog 1(作業中):

char *s = "test string";
const char *tmp = s;
printMe(tmp);

void printMe(const char *&buf) {
    printf("Given Str = %s", buf);
}

Prog 2(機能していません)

char *s = "test string";
printMe((const char *)s);     // typecasting not working

void printMe(const char *&buf) {
    printf("Given Str = %s", buf);
}

私が受け取るエラー:

x.cpp:10:15: warning: conversion from string literal to 'char *' is 
deprecated [-Wc++11-compat-deprecated-writable-strings]
char *s = "test string";
          ^
x.cpp:12:5: error: no matching function for call to 'printMe'
printMe(s);
^~~~~~~
x.cpp:6:6: note: candidate function not viable: no known conversion 
from 'char *' to 'const char *&' for 1st argument
void printMe(const char *&buf)
 ^
1 warning and 1 error generated.

ありがとう。

6
M. Rock

printMeは、constcharへの可変ポインターへの左辺値参照を取ります。

最初の例では、tmpはconstcharへの可変ポインター型の左辺値であるため、参照を問題なくバインドできます。
2番目の例では、(const char*)sは一時的なconst char*オブジェクトを作成します。可変オブジェクトへの左辺値参照は一時オブジェクトにバインドできないため、エラーが発生します。 printMeを変更してconst char* const&を取得すると、明示的なキャストの有無にかかわらず、呼び出しは成功します。

void printMe(const char * const& buf) {
    printf("Given Str = %s", buf);
}

int main() {
    char s[] = "test string";
    printMe(s);
}

Live on Colir

もちろん、printMeに渡されるオブジェクト(ポインター)を変更したくない場合は、参照を使用する理由はまったくありません。 const char*を取るだけです:

void printMe(const char * buf) {
    printf("Given Str = %s", buf);
}

int main() {
    char s[] = "test string";
    printMe(s);
}

Live on Colir

結局、これは次のようなものと同じ理由です。

void doSomething(const std::string& s) {}
int main() {
    doSomething("asdf");
}

この間動作します:

void doSomething(std::string& s) {}
int main() {
    doSomething("asdf");
}

ではない。一時オブジェクトが作成され、非constオブジェクトへの参照は一時オブジェクトにバインドできません。

5
Miles Budnek