I'm creating my own Matrix Class. When it comes to the "at" function used to change the value of a certain element, I have this.
T & at(unsigned int raw, unsigned int col)
{
return (_matrix.at(index(raw, col)));
}
knowing that
std::vector<T> _matrix;
It works perfectly for all types expect for booleans. I'm not able to do this operation.
matrix.at(1, 1) = true;
Which is weird because I have the same implementation as std::vector "at" function, which works with booleans.
Any ideas ? Thanks.
std::vector<bool>
is special from all other std::vector
specializations.
Its .at
member function does not return a reference to bool
, but a proxy object that can be assigned to and converted to bool
. Neither the proxy object, nor the converted bool
(which is a prvalue) can be bound to a bool&
as you try to do in the return
statement.
You must handle the case T = bool
in a special way, e.g. by forbidding it for your matrix class or by using std::vector<char>
instead of std::vector<bool>
when your T
is bool
:
using U = std::conditional_t<std::is_same_v<T, bool>, char, T>;
std::vector<U> _matrix;
and then return U&
instead of T&
wherever you return references. (This requires #include<type_traits>
and C++17 in this form, but can be adapted to C++11.)
or by using a wrapper around bool
, such as
struct A {
bool b;
};
that you store in the vector instead of bool
, so that you can still return references to the bool
member properly,
or, if you intend to use the packed storage mechanism which differentiates std::vector<bool>
from all other std::vector
specializations, you can return the proxy object from your .at
method and basically introduce the same special case that std::vector
has for your matrix class, but then you will need to take care of the special case everywhere in your matrix class:
decltype(auto) at(unsigned int raw, unsigned int col)
{
return _matrix.at(index(raw, col));
}
(removing the parentheses in the return statement is important in this case and requires C++14) or
std::vector<T>::reference at(unsigned int raw, unsigned int col)
{
return _matrix.at(index(raw, col));
}
It is very unfortunate that std::vector<bool>
is special in that way. Read more about this e.g. in this question and on the cppreference.com page for std::vector<bool>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With