Стандарт не требует этого для компиляции на любом наборе инструментов!
Сначала вспомните, что 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 ++ делает это тоже .
Я предполагаю, что реализация Visual Studio stdlib, которую вы все еще используете, не делает этого , но затем, чтобы добавить оскорбление травме, вы можете привязать временные ссылки к lvalue ссылкам в VS (если вы не используете режим соответствия), поэтому стандартная «универсальная» std::swap
функция работает до тех пор, пока вы не замените компилятор VS более строгим компилятором Clang.
В результате вы полагались на расширения для всех трех наборов инструментов, для которых он работал, и комбинация Clang on 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[]
lvalue? а можетstd::swap
оперировать rvalues и xvalues?