Я сделал аргумент функции const и потому что я хочу иметь возможность передавать ей "строковые литералы".
Если вам интересно, точный тип строковый литерал, подобный этому ...
"string literal"
... is const char[15]
. Так уж получилось, что std::string
имеет конструктор, который принимает const char*
, который const char[15]
автоматически распадается, поэтому строковый литерал привязывается к параметру const std::string&
.
(const char[15]) --> decay --> (const char*) --> bind --> std::string::string( const char* )
Это создает временный std::string
, который содержит копию строкового литерала. Ваша функция затем принимает этот временный std::string
как const std::string&
. Исходный временный код на самом деле не const
Является или нет первоначальный временный символ const
явно слабым в стандарте, но равен const
в C ++ 17, согласно другому ответу.
Однако мне интересно, можно ли изменить ссылку
Мне интересно, можно ли отбросить const на std :: string ссылка не определена.
Если вы хотите изменить временную, нет необходимости в const_cast
. Этот язык дает вам возможность привязываться к временным организациям не const
: ссылка rvalue
.
// this is a const lvalue reference
// it binds to temporaries
void addObjectToDictionary(int* obj, const std::string& name);
// this is an rvalue reference
// it also binds to temporaries, and will bind to temporaries instead of a
// const lvalue reference if both overloads exist
void addObjectToDictionary(int* obj, std::string&& name);
Ответ на заданный вами вопрос ...
Я просто хотел бы знать, однако, является ли временный объект std :: string, созданный при вызове функции, постоянным или нет.
... равен нет, временные не const
очевидно да для C ++ 17 согласно другому ответу. Тем не менее, y Вы также не должны брать временную ссылку const
lvalue и отбрасывать const
, потому что эта подпись также связывается с фактически const
объектами. Вместо этого вы можете привязать временное значение не const
, используя ссылочный параметр rvalue
.
В качестве бонуса, если вы хотите привязать напрямую к строковому литералу, вы можете сделать это:
// this templates functions that bind to the exact type of any string literal
template<std::size_t N>
void addObjectToDictionary(int* obj, const char ( &name )[N] );
Этот шаблон генерирует функции, которые связываются с точными типами строковых литералов любой длины. Это может быть немного за бортом.
РЕДАКТИРОВАТЬ
В комментариях есть предложение принять строку по значению (std::string
, без ссылки). Это также совершенно правильный способ «погрузить» строку в вашу функцию.
// this will bind to string literals without creating a temporary
void addObjectToDictionary(int* obj, std::string name);
То, что происходит здесь, немного по-другому. При передаче строкового литерала параметру const std::string&
вы получаете ссылку const
на временный std::string
. При передаче строкового литерала в простое старое значение std::string
то, что раньше было временным, теперь является вашим собственным объектом std::string
значения, как вы, * sh, созданным из строкового литерала.