8 Expressions [expr]

8.2 Postfix expressions [expr.post]

8.2.2 Function call [expr.call]

Вызов функции - это постфиксное выражение, за которым следуют круглые скобки, содержащие, возможно, пустой, разделенный запятыми список, initializer-clauses который составляет аргументы функции. Постфиксное выражение должно иметь тип функции или тип указателя функции. Для вызова функции, не являющейся членом, или статической функции-члена, постфиксное выражение должно быть либо lvalue, которое относится к функции (в этом случае function-to-pointer standard conversion подавляется в постфиксном выражении), либо оно должно иметь тип указателя функции. Вызов функции через выражение, тип функции которого отличается от типа функции определения вызываемой функции, приводит к неопределенному поведению ([dcl.link]). Для вызова нестатической функции-члена постфиксное выражение должно быть неявным ([class.mfct.non-static], [class.static]) или явным class member access , id-expressionкоторое является именем члена функции или pointer-to-member expression выбором члена функции; вызов осуществляется как член объекта класса, на который ссылается выражение объекта. В случае неявного доступа к члену класса подразумеваемый объект - это тот, на который указывает this. [ Note: Вызов функции-члена формы f() интерпретируется как (*this).f() (см. [class.mfct.non-static]). ] Если используется имя функции или функции-члена, имя может быть таким , и в этом случае соответствующая функция должна быть выбрана в соответствии с правилами в . Если выбранная функция не виртуальная или если в выражении доступа к члену класса указано a , эта функция вызывается. В противном случае вызывается его динамический тип выражения объекта; такой вызов называется . [ Динамический тип - это тип объекта, на который ссылается текущее значение выражения объекта. описывает поведение вызовов виртуальных функций, когда выражение объекта относится к объекту, находящемуся в процессе строительства или уничтожения. ]end noteoverloaded [over.match]id-expressionqualified-id final overrider virtual function callNote: [class.cdtor] end note

[ Note: Если используется имя функции или функции-члена, name lookup но не найдено объявление с таким именем, программа имеет неправильный формат. При таком вызове неявно не объявляется никакая функция. ]end note

Если postfix-expressionобозначает destructorтип выражения вызова функции void; в противном случае тип выражения вызова функции - это тип возвращаемого значения статически выбранной функции (т. е. игнорирование virtual ключевого слова), даже если тип фактически вызываемой функции отличается. Этот возвращаемый тип должен быть типом объекта, ссылочным типом или cv void.

Когда функция вызывается, каждый параметр ([dcl.fct]) должен быть инициализирован ([dcl.init], [class.copy], [class.ctor]) с соответствующим аргументом. Если функция является нестатической функцией-членом, this parameter объект функции должен быть инициализирован указателем на объект вызова, преобразованным, как если бы с помощью explicit type conversion. [ Note: Для этого преобразования нет проверки доступа или неоднозначности; проверка доступа и устранение неоднозначности выполняются как часть (возможно, неявного) оператора доступа к членам класса. См [class.member.lookup], [class.access.base]и [expr.ref]. ] При вызове функции параметры, имеющие объектный тип, должны иметь полностью определенный объектный тип. [ это по-прежнему позволяет параметру быть указателем или ссылкой на неполный тип класса. Однако это не позволяет параметру, передаваемому по значению, иметь неполный тип класса. ] Это определяется реализацией, заканчивается ли время жизни параметра, когда функция, в которой он определен, возвращается, или в конце включающего полного выражения. Инициализация и уничтожение каждого параметра происходит в контексте вызывающей функции. [ Доступ конструктора, функций преобразования или деструктора проверяется в точке вызова в вызывающей функции. Если конструктор или деструктор для параметра функции вызывает исключение, поиск обработчика начинается в области действия вызывающей функции; в частности, если вызываемая функция имеет обработчик, способный обработать исключение, этот обработчик не рассматривается. ]end noteNote: end noteExample: function-try-blockend example

postfix-expressionСеквенировали перед каждым expressionв expression-list и аргумент любого по умолчанию. Инициализация параметра, включая вычисление каждого связанного значения и побочный эффект, имеет неопределенную последовательность относительно инициализации любого другого параметра. [ Note: Все побочные эффекты оценок аргументов упорядочиваются до ввода функции (см. [intro.execution]). ] [end noteExample:

void f() {
  std::string s = "but I have heard it works even if you don't believe in it";
  s.replace(0, 4, "").replace(s.find("even"), 4, "only").replace(s.find(" don't"), 6, "");
  assert(s == "I have heard it works only if you believe in it"); // OK
}

end example] [ Note: Если операторная функция вызывается с использованием обозначения оператора, вычисление аргументов выполняется в порядке, указанном для встроенного оператора; см [over.match.oper]. ] [end noteExample:

struct S {
  S(int);
};
int operator<<(S, int);
int i, j;
int x = S(i=1) << (i=2);
int y = operator<<(S(j=1), j=2);

После выполнения инициализации значение i равно 2 (см. [expr.shift]), Но не указано, является ли значение j 1 или 2. ]end example

Результатом вызова функции является результат операнда вычисляемой return statement в вызываемой функции (если есть), за исключением вызова виртуальной функции, если тип возвращаемого значения последнего переопределителя отличается от типа возвращаемого значения статически выбранной функции, значение, возвращаемое последним переопределителем, преобразуется в тип возвращаемого значения статически выбранной функции.

[ Функция может изменять значения своих неконстантных параметров, но эти изменения не могут повлиять на значения аргументов, за исключением случаев, когда параметр имеет ссылочный тип ( ); если ссылка относится к типу, уточненному константой , необходимо использовать для отказа от константности, чтобы изменить значение аргумента. Если параметр имеет ссылочного типа временный объект введен в случае необходимости ( , , , , ). Кроме того, можно изменять значения непостоянных объектов с помощью параметров указателя. ]Note: [dcl.ref] const_­cast const [dcl.type] [lex.literal] [lex.string] [dcl.array] [class.temporary]end note

Функцию можно объявить так, чтобы она принимала меньше аргументов (путем объявления default arguments) или большего количества аргументов (с помощью многоточия ..., или параметра функции pack ([dcl.fct])), чем количество параметров в function definition. [ Note: Это означает, что, за исключением случаев использования многоточия (...) или пакета параметров функции, параметр доступен для каждого аргумента. ]end note

Если для данного аргумента нет параметра, аргумент передается таким образом, что принимающая функция может получить значение аргумента путем вызова va_­arg. [ Note: Этот абзац не применяется к аргументам, переданным в пакет параметров функции. Пакеты параметров функции раскрываются во время создания экземпляра шаблона ([temp.variadic]), поэтому каждый такой аргумент имеет соответствующий параметр при фактическом вызове специализации шаблона функции. ] , И стандартные преобразования выполняются на выражение аргумента. Аргумент, имеющий тип, - это тип . После этих преобразований, если аргумент не имеет арифметических операций, перечисления, указателя, указателя на член или типа класса, программа имеет неправильный формат. Передача потенциально оцененного аргумента наличия нетривиального конструктора копирования, нетривиального конструктора перемещения или нетривиального деструктора без соответствующего параметра условно поддерживается семантикой, определяемой реализацией. Если аргумент имеет целочисленный или перечисляемый тип, который подчиняется , или тип с плавающей запятой, который подчиняется , значение аргумента преобразуется в повышенный тип перед вызовом. Эти рекламные акции называются . end notelvalue-to-rvalue array-to-pointer function-to-pointer cv std​::​nullptr_­t converted void* class type integral promotionsfloating-point promotion default argument promotions

Рекурсивные вызовы разрешены, за исключением main function.

Вызов функции является lvalue, если тип результата является ссылочным типом lvalue или ссылкой rvalue на тип функции, xvalue, если тип результата является ссылкой rvalue на тип объекта, и prvalue в противном случае.