std::vector<bool>
является особенным для всех других std::vector
специализаций.
Его .at
функция-член не возвращает ссылку на bool
, но прокси-объект, который может быть назначен и преобразован в bool
. Ни прокси-объект, ни преобразованный bool
(который является prvalue) не может быть привязан к bool&
, как вы пытаетесь это сделать в операторе return
.
Вы должны обработать регистр T = bool
особым образом, например, запретив его для вашего класса матрицы или используя std::vector<char>
вместо std::vector<bool>
, когда ваш T
равен bool
:
using U = std::conditional_t<std::is_same_v<T, bool>, char, T>;
std::vector<U> _matrix;
и затем возвращает U&
вместо T&
везде, куда вы возвращаете ссылки. (Для этого требуется #include<type_traits>
и C ++ 17 в этой форме, но его можно адаптировать к C ++ 11.)
или с использованием обертки вокруг bool
, такой как
struct A {
bool b;
};
, который вы сохраняете в векторе вместо bool
, так что вы все равно можете правильно возвращать ссылки на элемент bool
,
или, если вы собираетесь использовать механизм упакованного хранилища, который различает std::vector<bool>
из всех других std::vector
специализаций, вы можете вернуть прокси-объект из вашего .at
метода и в основном представить тот же особый случай, который std::vector
имеет для вашего матричного класса, но тогда вам нужно будет позаботиться о специальном case везде в вашем матричном классе:
decltype(auto) at(unsigned int raw, unsigned int col)
{
return _matrix.at(index(raw, col));
}
(удаление скобок в операторе возврата важно в этом случае и требует C ++ 14) или
std::vector<T>::reference at(unsigned int raw, unsigned int col)
{
return _matrix.at(index(raw, col));
}
Это очень неудачно что std::vector<bool>
особенный в этом смысле. Узнайте больше об этом, например, в этом вопросе и на странице cppreference.com для std::vector<bool>
.