Поменяет ли swap() поведение undefined?

Я пытаюсь понять условия на std::swap из [С++ 11: utility.swap]. Шаблон определяется как

template <typename T> void swap(T &, T &)

(плюс некоторые детали noexcept) и как эффект "обмена значениями, хранящимися в двух местах".

Является ли следующая программа корректной?

#include <utility>

int main()
{
    int m, n;
    std::swap(m, n);
}

Если я сам написал код подкачки (т.е. int tmp = m; m = n; n = tmp;), он будет иметь поведение undefined, так как он будет пытаться преобразовать lvalue-to-rvalue в неинициализированный объект. Но стандартная функция std::swap, похоже, не имеет никаких условий, наложенных на нее, и не может быть выведено из спецификации, что существует любое значение lvalue-to-r и, следовательно, UB.

Требуется ли стандарту std::swap выполнить некоторую магию, которая четко определена на неинициализированных объектах?

Чтобы прояснить эту точку, рассмотрим функцию void f(int & n) { n = 25; }, которая никогда не имеет поведения undefined (поскольку она не читается из n).

Ответы

Ответ 1

Очень хороший вопрос. Однако я бы сказал, что это покрывается [res.on.arguments] §1:

Каждое из следующих утверждений относится ко всем аргументам к функциям, определенным в стандартной библиотеке С++, если только явно указано иначе.

  • Если аргумент функции имеет недопустимое значение (например, значение вне домена функции или указатель недействителен для его предполагаемого использования), поведение undefined.

Чтобы решить вашу озабоченность по поводу f(n), функция f из вашего вопроса не является частью стандартной библиотеки С++ и, следовательно, вышеприведенное предложение не относится к ней.

Ответ 2

Поскольку значение M равно undefined, я ожидаю, что он испортит вызов для обмена. Носовые демоны могут летать, когда вызывается своп.