Можно ли задать значение по умолчанию для параметра функции, когда мы передаем параметр по ссылке. в C ++
Например, когда я пытаюсь объявить такую функцию, как:
virtual const ULONG Write(ULONG &State = 0, bool sequence = true);
Когда я это делаю, выдает ошибку:
ошибка C2440: 'аргумент по умолчанию': невозможно преобразовать из 'const int' в 'unsigned long &' Ссылка, которая не является 'const', не может быть привязана к значению, отличному от lvalue
c++
pass-by-reference
default-value
Дрю Ноукс
источник
источник
WxWidgets style guide says "don't use templates" and they have good reasons
<- Screw std :: vector, я говорюОтветы:
Вы можете сделать это для константной ссылки, но не для неконстантной. Это связано с тем, что C ++ не позволяет привязать временную (в данном случае значение по умолчанию) к неконстантной ссылке.
Один из способов обойти это - использовать фактический экземпляр по умолчанию:
но это имеет очень ограниченное практическое применение.
источник
Об этом уже говорилось в одном из прямых комментариев к вашему ответу, но просто чтобы заявить об этом официально. Вы хотите использовать перегрузку:
Использование перегрузок функций также дает дополнительные преимущества. Во-первых, вы можете использовать любой аргумент по умолчанию:
Также возможно переопределить аргументы по умолчанию для виртуальных функций в производном классе, что позволяет избежать перегрузки:
Есть только одна ситуация, когда действительно необходимо использовать значение по умолчанию, и это в конструкторе. Невозможно вызвать один конструктор из другого, поэтому этот метод не работает в этом случае.
источник
d.f2(); // f2(int) called with '0' b.f2(); // f2(int) called with '0'
По-прежнему существует старый способ C предоставлять необязательные аргументы: указатель, который может иметь значение NULL, если он отсутствует:
источник
Этот небольшой шаблон поможет вам:
Тогда вы сможете:
источник
ByRef
live по памяти? Разве это не временный объект, который будет уничтожен при выходе из некоторой области (например, конструктора)?Нет, это невозможно.
Передача по ссылке подразумевает, что функция может изменить значение параметра. Если параметр не предоставляется вызывающей стороной и исходит из константы по умолчанию, какую функцию предполагается изменить?
источник
Есть две причины для передачи аргумента по ссылке: (1) для производительности (в этом случае вы хотите передать по ссылке const) и (2), потому что вам нужна возможность изменять значение аргумента внутри функции.
Я очень сомневаюсь, что использование unsigned long на современных архитектурах слишком сильно замедляет вас. Итак, я предполагаю, что вы собираетесь изменить значение
State
внутри метода. Компилятор жалуется, потому что константа0
не может быть изменена, так как это rvalue («не-lvalue» в сообщении об ошибке) и неизменяемое (const
в сообщении об ошибке).Проще говоря, вам нужен метод, который может изменить переданный аргумент, но по умолчанию вы хотите передать аргумент, который не может измениться.
Другими словами, не
const
ссылки должны относиться к фактическим переменным. Значение по умолчанию в функции signature (0
) не является реальной переменной. У вас та же проблема, что и:Если вы на самом деле не собираетесь вносить изменения
State
в метод, вы можете просто изменить его наconst ULONG&
. Но вы не получите от этого большого выигрыша в производительности, поэтому я бы порекомендовал изменить его на нереференсныйULONG
. Я заметил, что вы уже возвращаете aULONG
, и у меня есть скрытое подозрение, что его значением является значениеState
после любых необходимых изменений. В этом случае я бы просто объявил метод так:Конечно, я не совсем понимаю, что вы пишете и куда. Но это другой вопрос в другой раз.
источник
Вы не можете использовать постоянный литерал для параметра по умолчанию по той же причине, по которой вы не можете использовать его в качестве параметра для вызова функции. Ссылочные значения должны иметь адрес, постоянные ссылочные значения не должны (т.е. они могут быть r-значениями или константными литералами).
Убедитесь, что у вашего значения по умолчанию есть адрес, и все в порядке.
Я использовал этот шаблон несколько раз, когда у меня был параметр, который мог быть переменной или нулем. Обычный подход заключается в том, чтобы пользователь передавал указатель в этом случае. Они передают NULL-указатель, если не хотят, чтобы вы вводили значение. Мне нравится подход с нулевым объектом. Это облегчает жизнь вызывающим абонентам, не сильно усложняя код вызываемого абонента.
источник
Я думаю, что нет, и причина в том, что значения по умолчанию оцениваются как константы, а значения, передаваемые по ссылке, должны иметь возможность изменяться, если вы также не объявите это постоянной ссылкой.
источник
Другой способ мог быть следующим:
то возможны следующие вызовы:
источник
источник
В случае OO ... Сказать, что данный класс имеет и "Default" означает, что это значение по умолчанию (значение) должно быть объявлено, соответственно, и затем может быть использовано как параметр по умолчанию, например:
О вашем методе ...
Это решение вполне подходит, поскольку в этом случае «Глобальная разбивка на страницы по умолчанию» является единственным «ссылочным» значением. У вас также будет возможность изменять значения по умолчанию во время выполнения, например, конфигурация «глобального уровня», например: пользовательские настройки навигации по страницам и т. Д.
источник
Это возможно с квалификатором const для State:
источник
источник
Для этого тоже есть довольно подвох:
В этом случае вы должны вызвать его с помощью
std::move
:Это всего лишь забавный обходной путь, я категорически не рекомендую использовать его в реальном коде!
источник
У меня есть обходной путь, см. Следующий пример значения по умолчанию для
int&
:Вы можете сделать это для любого тривиального типа данных, например
bool
,double
...источник
Определите 2 функции перегрузки.
источник
Ответ довольно прост, и я не очень хорошо объясняю, но если вы хотите передать значение по умолчанию неконстантному параметру, который, вероятно, будет изменен в этой функции, следует использовать его следующим образом:
источник