"Hello, World"
- это , а не типа const char*
. Он имеет тип const char[13]
и является lvalue, а не rvalue.
Когда вы используете "Hello, World"
в контексте, в котором он неявно преобразуется в const char*
, указывающий на его начальный элемент, результирующий указатель является значением r (потому что это временный объект, являющийся результатом неявного преобразования.
Например, в GCC 4.5.2 метод, который возвращает тип int
в отличие от int&
, обрабатывается как возвращающий int&&
.
Если вы вызываете функцию, которая возвращает значение (например, int
), тогда это выражение вызова функции является выражением rvalue. Если вы вызываете функцию, которая возвращает ссылку на lvalue (например, int&
), то это выражение вызова функции является выражением lvalue.
Как отличить переменную от строки, скомпилированной компилятором?
Вы не можете, на самом деле: нет никакой разницы между "Hello, World"
и любыми другими const char[13]
, которые вы могли бы объявить.
Что касается хранения const char*
s или любых других типов указателей в контейнере стандартной библиотеки, таких как std::vector
, контейнер не будет касаться указанных данных: контейнер просто собирается создавать, перемещать, копировать и уничтожить указатели.
Если вам нужно управлять указанными данными, вам нужно сделать это самостоятельно, написав класс для управления указанным объектом (очень похоже на класс интеллектуальных указателей). Идиома написания класса для управления ресурсом, подобного этому, называется «Получение ресурсов - инициализация» (RAII) или «Управление ресурсами, связанными с областью действия» (SBRM).