C ++ 11 - Отличительные значения указателей - PullRequest
2 голосов
/ 18 марта 2011

Как я могу отличить переменную как строку, созданную компилятором?

Например, если значение "Hello, World" имеет тип const char*.const char* само по себе не означает, что указатель не может быть изменен.Указатель char* const не может быть изменен, но это не то, что скомпилировано компилятором.

Означает ли это, что для любого контейнера, содержащего const char*, данные должны копироваться другими способами, кромеСемантика перемещения C ++?Есть ли способ просто переместить строки, созданные компилятором, и оставить все остальные строки в покое?

Например, в GCC 4.5.2 метод, который возвращает тип int в отличие от int&, являетсярассматривается как возвращение int&&.Я не знаю, должен ли фактический стандарт быть таким, но GCC в настоящее время делает это.

Редактировать: Чтобы уточнить, я имею в виду, что фактическая память, на которую указывает указатель, должнабыть скопирован.Это означает, что должна быть выделена новая память и что данные из указателя должны быть скопированы в новое местоположение.

Ответы [ 2 ]

9 голосов
/ 18 марта 2011

"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).

0 голосов
/ 18 марта 2011

Означает ли это, что для любого контейнера, который содержит const char *, данные должны быть скопированы другими способами, кроме семантики перемещения C ++?

Это означает, что указатель скопирован. Ни больше ни меньше. Для работы контейнера необходимо скопировать указатель .

...