1

Whist compiling the following code from this S/O answer, I keep getting errors due to binding issues.

class my_matrix {
  std::vector<std::vector<bool> >m;
public:
  my_matrix(unsigned int x, unsigned int y) {
    m.resize(x, std::vector<bool>(y,false));
  }
  class matrix_row {
    std::vector<bool>& row;
  public:
    matrix_row(std::vector<bool>& r) : row(r) {
    }
    bool& operator[](unsigned int y) {
      return row.at(y);
    }
  };
  matrix_row& operator[](unsigned int x) {
    return matrix_row(m.at(x));
  }
};
// Example usage
my_matrix mm(100,100);
mm[10][10] = true;

Here is the report

m.cpp:16:14: error: non-const lvalue reference to type 'bool' cannot bind to a
      temporary of type 'reference' (aka '__bit_reference<std::__1::vector<bool,
      std::__1::allocator<bool> > >')
      return row.at(y);
             ^~~~~~~~~
m.cpp:20:12: error: non-const lvalue reference to type 'my_matrix::matrix_row'
      cannot bind to a temporary of type 'my_matrix::matrix_row'
    return matrix_row(m.at(x));
           ^~~~~~~~~~~~~~~~~~~

Having researched into this, I realise that a Bool vector is not the same as a normal c++ vector. Therefore, I can avoid the first error by changing it to an int vector.

The second error in the last line is a little more confusing. I have looked at this question but I still can't figure out what to do.

** Edit **

Given the answer/comment, I feel like something like this should work,

matrix_row& operator[](unsigned int x) {
    std::vector<int> e = m.at(x);
    matrix_row f = matrix_row(e);
    return f;

It does not. This appears to create variables with memory though (e and f)?

AngusTheMan
  • 564
  • 1
  • 6
  • 15
  • 2
    `matrix_row(m.at(x))` is a temporary, constructed from vector element. You are trying to return an lvalue reference - it can't refer to a temporary. It doesn't work for the exact same reason `vector` doesn't work - you are returning a proxy object, rather than a reference to the actual element. – Igor Tandetnik Sep 17 '18 at 14:59
  • @IgorTandetnik Thank you for your comment, it really helped! From what I understand I now need to create a variable with some assigned piece of memory and then return that in the function? – AngusTheMan Sep 17 '18 at 15:23
  • Return `matrix_row` by value, or return `std::vector` reference. You can't have it both ways – Igor Tandetnik Sep 17 '18 at 16:12
  • @IgorTandetnik Thank you, so I removed the `&` in the function definition and now have the following error, `ld: can't open output file for writing: m./m, errno=2 for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) `any idea? – AngusTheMan Sep 17 '18 at 16:35
  • 1
    My guess would be, the executable you are trying to build is still running, likely from previous experiments. – Igor Tandetnik Sep 17 '18 at 16:46

1 Answers1

0

You're trying to bind a non-const lvalue reference to an rvalue. That's not possible.

Note that although binding a const reference, or non-const rvalue reference to an rvalue would be syntactically correct, it would be wrong, because the temporary that you create stops existing once the function returns, and so having a reference to the temporary is not useful.

You should probably return an object from the function, rather than a reference.


Edit:

No, your new suggestion cannot work either, and the reason is still same. The local object e stops exising once the function returns, so having a reference to it is not useful.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • thank you for your answer, it really helped! I have been trying to figure out how I can avoid this, I thought perhaps if I create a variable first and then return that, it might be assigned some memory (as in my edit), unfortunately, this didn't work. Could you elaborate *how* to avoid this? Many thanks – AngusTheMan Sep 17 '18 at 15:45
  • @AngusTheMan the new attempt has the same problem. You return a reference to an object which doesn't exist once the funtion ends. As I said, you should probably return an object, rather than a reference. – eerorika Sep 17 '18 at 15:55
  • Thank you, so I removed the `&` in the function definition and now have the following error, `ld: can't open output file for writing: m./m, errno=2 for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) `any idea? – AngusTheMan Sep 17 '18 at 16:36