2

I am working on a matrix view class, of which constructor takes a matrix as a parameter and binds it to a const reference member. I would very much like to avoid binding rvalues, since they don't bind via a constructor parameter, and we end up with a dangling reference. I came up with the following (simplified code):

struct Foo{};

class X
{
    const Foo& _foo;
public:    
    X(const Foo&&) = delete;       // prevents rvalue binding
    X(const Foo& foo): _foo(foo){} // lvalue is OK
};

Foo get_Foo()
{
    return {};
}

const Foo get_const_Foo()
{
    return {};
}

Foo& get_lvalue_Foo()
{
    static Foo foo;
    return foo;
}

int main() 
{
//  X x1{get_Foo()};        // does not compile, use of deleted function
//  X x2{get_const_Foo()};  // does not compile, use of deleted function
    X x3{get_lvalue_Foo()}; // this should be OK
}

Basically I delete the constructor that takes const Foo&& as a parameter. Note that I need the const since otherwise someone may return const Foo from a function, and in that case it will bind to the const Foo& constructor.

Question:

Is this the correct paradigm of disable rvalue binding? Am I missing something?

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • There isn't really much to say here regarding programming; I think it should be on codereview.se. – edmz Oct 20 '15 at 19:15
  • `const Foo&&` is pointless –  Oct 20 '15 at 19:17
  • 2
    @DieterLücking That's what I thought first also, but it's not. Try removing the `const` and the second commented line will compile. – vsoftco Oct 20 '15 at 19:17
  • 1
    Side note: `const Foo get_const_Foo()` is already fishy –  Oct 20 '15 at 19:24
  • @DieterLücking Totally agree, but I've seen it in production code (Eigen library uses it, and need to take care of it). See e.g. http://stackoverflow.com/a/33202145/3093378, which was the source for this question. – vsoftco Oct 20 '15 at 19:25
  • 2
    I don't see anything wrong, this is exactly what [`reference_wrapper`](http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/reference_wrapper) does. Its deleted constructor takes `T&&` because the other constructor takes `T&`. You could do the same and have `View` be a mutable view into the matrix, while `View` is a const view. – Praetorian Oct 20 '15 at 19:29
  • @Praetorian Thanks for the link! The `reference_wrapper` seems the most elegant way of doing it. – vsoftco Oct 20 '15 at 19:31

0 Answers0