Вывод аргумента шаблона для 'char *'

У меня есть функция ниже (просто для воспроизведения проблемы):

template <typename KeyT>
void func(const KeyT cptr) {
  std::cout << typeid(KeyT).name() << std::endl;
}

Я хотел бы назвать это строковым литералом, как показано ниже:

func<char*>("literal");

Но в итоге я получаю предупреждение ниже:

warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wc++11-compat-deprecated-writable-strings]

Мне нужно использовать char* как мой тип ключа, и я ожидал, что TAD рассмотрит param type как const char* в целом, поскольку я не беру его по ссылке.

Предупреждение поставляется с компиляторами clang и g++.

Как выводится param type здесь?

Спасибо заранее.

Ответы

Ответ 1

Я ожидал, что TAD рассмотрит тип параметра как const char *...
Как выводится здесь параметр param?

template <typename KeyT>
void func(const KeyT cptr)

Обратите внимание, что const является определителем на KeyT сам, это означает, что если KeyT является указателем, то cptr будет указателем const, а не указателем на const.

"literal" является строковым литералом с типом const char[8], который может распасться на const char*. Тогда KeyT может быть выведено как const char*, тогда тип cptr будет const char* const.

Вы указываете тип аргумента шаблона как char*, а затем cptr a char* const. Но из С++ 11 неявно преобразование строкового литерала в char* не допускается, так как литералы const.

Зачем вам нужен тип параметра шаблона char*? Чтобы изменить его внутри функции? Обратите внимание, что изменение строкового литерала приведет к UB. Вы можете передать массив char, например:

char my_chararray[] = "literal";
func<char*>(my_chararray); // or just func(my_chararray);

Ответ 2

Здесь нет вычитания: вы явно указали, что параметр шаблона char*.

То, что вам не хватает, заключается в том, что замена параметров не является текстовым поиском и заменой: он фактически следует логическим правилам для системы типов. const KeyT cptr объявляет экземпляр const типа KeyT — когда KeyT равно char*, объявление параметра становится char *const cptr.