Вы можете добавить новую перегрузку, удобную для использования в строковых литералах. Это на самом деле не наука но только эвристики:
void f(const char* p); // potential literal
void f(char *p); // pointer to non-const
Еще одна идея будет принимать преимущество, что литералы действительно массивы:
template <int N>
void f(const char (&_)[N]); // potential literal
Обратите внимание, что они не совсем обнаружить буквальным vs. не литерал, а скорее некоторые другие функции. const char* p = createANewString(); f(p);
будет разрешен к f(const char*)
, и const char x[] = { 'A', 'b', 'c', '\0' };
разрешит шаблон. Ни один из них не является литералами, но вы, вероятно, тоже не хотите изменять.
Как только вы сделаете это изменение, должно быть легко узнать, где вызывается каждая из перегрузок.
Это все работает на том основании, что основная функция не должна принимать аргумент как const char*
, если он изменяет его внутренне и что проблема, с которой вы сталкиваетесь, заключается в том, что для обратной совместимости ваш компилятор разрешает вызов функции, которая принимает указатель на не-const с литералом ...
Я не понимаю, почему это имеет значение. Вы можете обрабатывать указатель на первый элемент массива 'const char' точно так же, независимо от того, был ли он создан строковым литералом или нет. –
@sftrabbit Я думаю, есть две потенциальные проблемы: это строка с нулевым завершением? И это указатель на один символ? – juanchopanza
@MM: Скажите, что ???? Литерал * не * временный. Это * наименее * временный тип объекта, так как его продолжительность - это вся программа. –