Я пишу программу, которая должна обрабатывать как строки 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)
,
Мой вопрос, если, как программа на С ++, строковый литерал, ("ambiguous"
) является std :: string, почему она будет приведена к char*
а затем сопоставить функцию hello(char* c)
вместо того, чтобы оставаться как std :: string и соответствовать hello(std::string s)
?
Я знаю, что могу прагму или -что-то из предупреждения (и что я могу привести char * к string без беспокойства), но я хочу знать, почему компилятор даже потрудился бы выполнить это приведение, и если есть способ сказать ему не , Я компилирую с g ++ 4.4.3.
Спасибо.
Строковые литералы как "ambiguous"
не тип std::string
, std::string
это только библиотека, без какой-либо языковой магии. Тип строкового литерала на самом деле const char[N]
, где N
длина литерала.
По историческим причинам (обратная совместимость) строковые литералы неявно преобразуются в char*
(нарушая const-правильность). Это встроенное преобразование предпочтительнее «определенного пользователем» преобразования в std::string
вот почему он называет char*
функция и дает вам предупреждение.
Если вы измените подпись hello
в hello(const char* c)
это, вероятно, больше не будет предупреждать вас (но все равно не вызовет std::string
версия, для этого нужно ручное приведение).
Вы ошибаетесь: «как программа на С ++, строковый литерал, (« неоднозначный ») является std :: string»
(«неоднозначный») — это не std :: string, это массив символов.
Вот почему его называют void hello (char * c).