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

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

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

, что может раздражать preety.

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

Ответы [ 4 ]

9 голосов
/ 17 июня 2009

Вам необходимо пройти по константной ссылке:

Для:

void DoSomethingByVal(String Str);

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

Для:

void DoSomethingByRef(String const& Str);

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

2 голосов
/ 17 июня 2009

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

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

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

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

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

void DoSomethingByRef(const String &Str);
0 голосов
/ 17 июня 2009

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

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

0 голосов
/ 17 июня 2009

Марка:

DoSomethingByRef (const String & str);

...