Еще одна причина, о которой еще никто не упомянул - передача по ссылке const
позволяет компилятору создавать и передавать временный объект, не генерируя предупреждение, если входное значение не является точным типом, объявленным в параметре, но Тип имеет конструктор, который поддерживает передаваемый тип.
Например:
void foo(const std::string &s)
{
...
}
foo("hello"); // OK
foo()
ожидает std::string
, но вместо этого получает const char*
. Поскольку std::string
имеет конструктор, который принимает const char*
, компилятор генерирует код, который эффективно делает это:
std::string temp("hello");
foo(temp);
Компилятор знает, что параметр const
, временное значение не будет изменено foo()
, а временное будет отброшено после выхода foo()
, поэтому он не жалуется на необходимость создания временного.
То же самое происходит, если параметр передается по значению (const
или не- const
, это не имеет значения) вместо ссылки:
void foo(const std::string s)
{
...
}
void bar(std::string s)
{
...
}
foo("hello"); // OK
bar("world"); // OK
Это фактически так же, как это:
{
std::string temp1("hello");
foo(temp1);
}
{
std::string temp2("world");
bar(temp2);
}
Опять же, компилятор не жалуется, так как знает, что временное не влияет на вызывающий код, и любые изменения, внесенные во временное в bar()
, будут безопасно отброшены.
Если бы параметр был ссылкой не const
, передача const char*
выдаст предупреждение о временном объекте, который должен быть создан для удовлетворения привязки ссылки. Предупреждение состоит в том, что вы должны знать, что любые изменения, вносимые функцией во временную (поскольку она не const
), будут потеряны при выходе из функции, что может повлиять или не повлиять на вызывающий код. Обычно это признак того, что временное не должно использоваться в этой ситуации:
void foo(std::string &s)
{
...
}
foo("hello"); // warning!