Имеется небольшой шаблон функции, который пиинимает в качестве аргументов две ссылки на переменные одинакового типа и меняет их значения местами. При этом когда передаю в функцию два члена вектора типа int, то все работает. Но если vectot<bool>, то нужно перегрузить функцию и вместо
template<typename T>
void fun (T & a, T & b)
{
T temp = a;
a = b;
b = temp;
return;
}
Написать
template<typename T>
void fun (T && a, T && b)
{
T temp = a;
a = b;
b = temp;
return;
}
Почему так?
Спецификация языка С++ позволяет реализовать std::vector<bool> не как обычный вектор из значений bool, а как специализированный упакованный битовый массив, в котором каждое булевское значение хранится в одном бите. Так как в С++ невозможно создать ссылку на отдельный бит, те методы вектора, которые обычно возвращают ссылку на его элемент (например, operator []), в случае std::vector<bool> возвращают не ссылку bool &, а специальный временный прокси-объект. Этот прокси-объект и реализует чтение и запись отдельного бита.
Т.е. запросто может получиться так, std::vector<bool>::reference - это совсем не ссылочный тип bool &, а некий определяемый реализацией класс-тип, реализующий/симулирующий поведение обобщенной ссылки. Так как возвращаемый объект этого типа является временным, его невозможно никуда передать по неконстантной lvalue-ссылке. А по rvalue-ссылке - можно.
Это, в частности, означает, что std::vector<bool> не обязательно соответствует требованиям, накладываемым на стандартный контейнер.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости