Стандарт не вимагає цього компілювати на будь-якій ланцюжку інструментів!
Спочатку нагадайте, що vector<bool>це дивно, і підписка на нього дає вам тимчасовий об'єкт типу проксі, який називається std::vector<bool>::reference, а не фактичним bool&.
Повідомлення про помилку говорить вам, що він не може прив’язати це тимчасове значення до constнецінової посилання в загальній template <typename T> std::swap(T& lhs, T& rhs)реалізації.
Розширення!
Однак виявляється, що libstdc ++ визначає перевантаження для цього std::swap(std::vector<bool>::reference, std::vector<bool>::reference), але це розширення до стандарту (або, якщо він знаходиться там, я не можу знайти жодних доказів для цього).
libc ++ теж робить це .
Я здогадуюсь, що реалізація stdlib Visual Studio, яку ви все ще використовуєте, не робить , але потім, щоб додати образи до травми, ви можете прив’язати тимчасових користувачів до значення цінностей у VS (якщо ви не використовуєте режим відповідності), тож стандартна, "загальна" std::swapфункція працює, поки ви не заміните компілятор VS на більш жорсткий компілятор Clang.
Як результат, ви покладаєтесь на розширення на всіх трьох ланцюжках інструментів, для яких це працювало для вас, а комбінація Clang у Windows є єдиною, яка фактично демонструє чітке дотримання.
(На мою думку, ці три ланцюжки інструментів повинні були діагностувати це, щоб ви не перевозили непереносний код весь цей час. 😊)
Що тепер?
Можливо, заманливо додати власну спеціалізацію std::swapта std::vector<bool>::reference, але вам це не дозволяється робити для стандартних типів; Дійсно, це суперечить перевантаженням, які libstdc ++ та libc ++ вибрали як розширення.
Отже, щоб бути портативними та сумісними, вам слід змінити код .
Можливо, хороший старомодний:
const bool temp = vb[0];
vb[0] = vb[1];
vb[1] = temp;
Або скористайтеся спеціальною статичною функцією члена, яка робить саме те, що ви хотіли :
std::vector<bool>::swap(vb[0], vb[1]);
Також написано так:
vb.swap(vb[0], vb[1]);
operator[]значення? і можеstd::swapпрацювати на rvalues і xvalues?