#c
#c #c
Вопрос:
Я видел некоторый код, в котором есть метод с некоторыми аргументами по умолчанию, которые имеют объектный тип, и мне стало интересно, что происходит, когда аргументы по умолчанию не указаны вызывающим. В «Языке программирования C » Страуструп говорит следующее:
Тип аргумента по умолчанию проверяется во время объявления функции и вычисляется во время вызова.
Например, если существует метод, объявленный подобным образом, будет ли новая строка создаваться каждый раз, когда этот метод вызывается без передачи default_string
?:
void foo(int param, std::string default_string = {});
Причина, по которой я задавался этим вопросом, заключалась в том, что если бы я реализовал такой метод, при котором вызывающие абоненты чаще всего не предоставляют аргументы по умолчанию, было бы лучше вообще не использовать аргументы по умолчанию и определить два метода с этими аргументами и без них, чтобы избежать дорогостоящего построения неиспользуемых аргументов?
Комментарии:
1. Это действительно зависит от того, как аргумент используется в функции. Если это необходимо, вам придется создать его рано или поздно. Скорее всего, создание пустой строки не так дорого, как вы думаете, и если это не точка доступа в вашей программе, вы не сможете заметить разницу.
2. В большинстве случаев предотвращение дублирования кода предпочтительнее преждевременной оптимизации.
Ответ №1:
ДА.
#include <iostream>
struct Object {
Object(bool expensive = true) {
if (expensive) {
std::cout << "Oh, I am so expensive!" << std::endl;
} else {
std::cout << "Ah, this was cheap." << std::endl;
}
}
};
void foo(Object o = {}) {}
int main() {
foo(Object(true));
foo(Object(false));
foo();
foo();
return 0;
}
[:~/tmp] $ g -std=c 2a constr2.cpp amp;amp; ./a.out
Oh, I am so expensive!
Ah, this was cheap.
Oh, I am so expensive!
Oh, I am so expensive!
Обратите внимание, что компилятор не может опустить конструкцию Object
, если он не может доказать, что у нее нет побочных эффектов. В примере, даже если он понимает, что o
это не будет использоваться в теле foo
, он не может пропустить печать.