Как избежать явного вызова конструктора при передаче временного объекта по ссылке в C++?

StackOverflow https://stackoverflow.com/questions/1008272

  •  06-07-2019
  •  | 
  •  

Вопрос

Допустим, у меня есть класс:

class String
{
public:
     String(char *str);
};

И две функции:

void DoSomethingByVal(String Str);
void DoSomethingByRef(String &Str);

Если я вызову DoSomethingByVal следующим образом:

DoSomethingByVal("My string");

компилятор определяет, что он должен создать временный объект String и вызвать конструктор char*.

Однако, если я попытаюсь использовать DoSomethingByRef таким же образом, я получу ошибку «Невозможно преобразовать параметр из 'char *' в 'String &'».

Вместо этого мне нужно явно создать экземпляр:

DoSomethingByRef(String("My string"));

что может сильно раздражать.

Есть ли способ избежать этого?

Это было полезно?

Решение

Вам нужно передать константную ссылку:

Для:

void DoSomethingByVal(String Str);

В этой ситуации компилятор сначала создает временную переменную.Затем временная переменная копируется в параметр.

Для:

void DoSomethingByRef(String const& Str);

В этой ситуации компилятор создает временную переменную.Но временные переменные не могут быть привязаны к ссылке, они могут быть привязаны только к константной ссылке, поэтому исходную функцию нельзя вызвать.Обратите внимание, что конструктор объектов std::string принимает константную ссылку - это параметр конструктора копирования, и поэтому первая версия работает, поскольку временная версия привязана только к константному ссылочному параметру конструктора копирования.

Другие советы

Хм, я не уверен, если

void DoSomethingByRef(String &Str);
DoSomethingByRef(String("My string"));

на самом деле будет компилироваться. Значение r не может связываться со ссылкой на неконстантный (поскольку ссылка на неконстантный указывает, что вы измените значение, и не имеет смысла изменять временное значение). Вы уверены, что не делаете:

String str("My string");
DoSomethingByRef(str);

Если вы хотите, чтобы DoSomethingByVal принял значение r, параметр должен быть ссылкой на const:

void DoSomethingByRef(const String &Str);

Делать:

DoSomethingByRef(const String &str);

" Моя строка " это не строка, это c-строка, символ *, если хотите. Вам нужно поместить эту c-строку в объект String, а затем вы можете передать новый объект String по ссылке.

Еще один момент: вы уже передаете символ * ... он довольно легкий, просто указатель. Зачем беспокоиться о передаче нового объекта по ссылке? Просто выделите новый объект внутри этого конструктора из кучи и скопируйте в него строку c.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top