c ++ неявное преобразование строки в char * соответствует неверной сигнатуре функции

Я пишу программу, которая должна обрабатывать как строки 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.

Спасибо.

1

Решение

Строковые литералы как "ambiguous" не тип std::string, std::string это только библиотека, без какой-либо языковой магии. Тип строкового литерала на самом деле const char[N], где N длина литерала.

По историческим причинам (обратная совместимость) строковые литералы неявно преобразуются в char* (нарушая const-правильность). Это встроенное преобразование предпочтительнее «определенного пользователем» преобразования в std::stringвот почему он называет char* функция и дает вам предупреждение.

Если вы измените подпись hello в hello(const char* c) это, вероятно, больше не будет предупреждать вас (но все равно не вызовет std::string версия, для этого нужно ручное приведение).

4

Другие решения

Вы ошибаетесь: «как программа на С ++, строковый литерал, (« неоднозначный ») является std :: string»

0

(«неоднозначный») — это не std :: string, это массив символов.

Вот почему его называют void hello (char * c).

0
По вопросам рекламы [email protected]