错误:无法将“bool&”类型的非常量左值引用绑定到“bool”类型的右值

adr*_*del 5 c++ boolean matrix c++17

我正在创建自己的矩阵类。当谈到用于更改某个元素的值的“at”函数时,我有这个。

T & at(unsigned int raw, unsigned int col)
{
    return (_matrix.at(index(raw, col)));
}
Run Code Online (Sandbox Code Playgroud)

知道

std::vector<T>  _matrix;
Run Code Online (Sandbox Code Playgroud)

它适用于所有类型的布尔值。我无法执行此操作。

matrix.at(1, 1) = true;
Run Code Online (Sandbox Code Playgroud)

这很奇怪,因为我的实现与 std::vector "at" 函数相同,它适用于布尔值。

有任何想法吗 ?谢谢。

wal*_*nut 6

std::vector<bool>与所有其他std::vector专业相比,它是特殊的。

它的.at成员函数不返回对 的引用bool,而是返回一个可以赋值和转换为 的代理对象bool。代理对象和转换后的对象bool(纯右值)都不能bool&像您在语句中尝试那样绑定到 a return

T = bool您必须以特殊方式处理这种情况,例如通过禁止您的矩阵类或使用std::vector<char>而不是std::vector<bool>当您Tbool

using U = std::conditional_t<std::is_same_v<T, bool>, char, T>;

std::vector<U>  _matrix;
Run Code Online (Sandbox Code Playgroud)

然后返回U&而不是T&返回引用的任何地方。(这需要#include<type_traits>这种形式的 C++17,但可以适应 C++11。)

或者使用包装器bool,例如

struct A {
    bool b;
};
Run Code Online (Sandbox Code Playgroud)

您存储在向量中而不是存储在向量中,以便您仍然可以正确bool返回对该成员的引用,bool

或者,如果您打算使用std::vector<bool>与所有其他std::vector专业化不同的打包存储机制,您可以从您的方法返回代理对象.at,并基本上引入与您的矩阵类相同的特殊情况std::vector,但是您将需要处理矩阵类中随处可见的特殊情况:

decltype(auto) at(unsigned int raw, unsigned int col)
{
    return _matrix.at(index(raw, col));
}
Run Code Online (Sandbox Code Playgroud)

(在这种情况下,删除 return 语句中的括号很重要,并且需要 C++14)或

std::vector<T>::reference at(unsigned int raw, unsigned int col)
{
    return _matrix.at(index(raw, col));
}
Run Code Online (Sandbox Code Playgroud)

非常不幸的是,这std::vector<bool>很特别。阅读有关此问题的更多信息,例如在这个问题和 cppreference.com 页面上std::vector<bool>