Вывод аргумента шаблона для '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
.