Стандарт не требует, чтобы это компилировалось на любом наборе инструментов!
Сначала вспомните, что vector<bool>
странно, и подписка на него дает вам временный объект прокси-типа с именем std::vector<bool>::reference
, а не фактическое bool&
.
Сообщение об ошибке сообщает, что оно не может привязать это временное значение к ссылке не-1010 * lvalue в общей реализации template <typename T> std::swap(T& lhs, T& rhs)
.
Расширения!
Однако оказывается, что libstdc ++ определяет перегрузку для std::swap(std::vector<bool>::reference, std::vector<bool>::reference)
, но это расширение стандарта (или, если оно там, я могуне нашел никаких доказательств этого).
libc ++ делает это тоже .
Я бы предположил, что реализация Visual Studio stdlib, которую вы все еще используете, не , но затем, чтобы добавить оскорбление к травме , вы можете привязать временные ссылки к lvalue ссылкам в VS (если вы не используете режим соответствия), поэтому стандартный, «универсальный»,std::swap
функция работает, пока вы не замените компилятор VS на stricter Clang compiler.
В результате вы полагались на расширения для всех трех наборов инструментов, для которых он работал, и комбинация Clang для Windows - единственная, которая действительно демонстрирует строгое соответствие.
(По моему мнению, эти три набора инструментов должны были диагностировать это , чтобы вы не отправляли непереносимый код все это время. 10)
Что теперь?
Может быть заманчиво добавить свою собственную специализацию 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]);