Подтвердить что ты не робот

Каков порядок разрушения функциональных параметров?

Это продолжение моего предыдущего вопроса Каков порядок уничтожения аргументов функции?, потому что я случайно путал аргументы с параметрами. Благодаря Columbo и T.C. для освобождения меня от терминологической путаницы в комментариях к этому вопросу.

Если тело некоторой функции f с параметрами p_1,..., p_n типов T_1,..., T_n соответственно выдает исключение, заканчивает или возвращает, в каком порядке разрушаются параметры и почему? Пожалуйста, предоставьте ссылку на стандарт, если это возможно.

Примеры:

template <typename ... Args>
void f(Args ... params) {} // in what order are params destroyed?

void f(T1 p1, T2 p2, T3 p3) {} // in what order are p1, p2 and p3 destroyed?
4b9b3361

Ответ 1

Точный момент времени, в который были уничтожены параметры, неуказан:

CWG решил не указывать, уничтожены ли объекты параметров сразу после вызова или в конце полного выражения, к которому принадлежит вызов.

Порядок, в котором строятся параметры, также не указан, но поскольку функциональные параметры имеют масштаб блока, хотя их порядок построения не указан, разрушение происходит в обратном порядке построения. Например. Рассмотрим

#include <iostream>

struct A {
    int i;
    A(int i) : i(i) {std::cout << i;}
    ~A() {std::cout << '~' << i;} 
};

void f(A, A) {}

int main() {
    (f(0, 1), std::cout << "#");
}

печатает 10#~0~1 с GCC и 01#~1~0 с Clang; они строят параметры в разных порядках, но оба они уничтожаются в обратном порядке построения, в конце полного выражения происходит вызов (а не справа после возвращения к вызывающей стороне). VС++ печатает 10~0~1#.