Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing temporaries as non-const references in C++

I have the following piece of code, as an example dec_proxy attempts to reverse the effects of the increment operator upon the type that is executed in a complex function call foo - which btw I cannot change the interface of.

#include <iostream>

template<typename T>
class dec_proxy
{
public:
   dec_proxy(T& t)
   :t_(t)
   {}

   dec_proxy<T>& operator++()
   {
      --t_;
      return *this;
   }

private:
   T& t_;
};

template<typename T, typename S, typename R>
void foo(T& t, S& s, R& r)
{
  ++t;
  ++s;
  ++r;
}

int main()
{
   int i = 0;
   double j = 0;
   short  k = 0;

   dec_proxy<int> dp1(i);
   dec_proxy<double> dp2(j);
   dec_proxy<short> dp3(k);

   foo(dp1,dp2,dp3);

   //foo(dec_proxy<int>(i),     <---- Gives an error
   //   dec_proxy<double>(j),     <---- Gives an error
   //   dec_proxy<short>(k));      <---- Gives an error 

   std::cout << "i=" << i << std::endl;

   return 0;
}

The problem is that for the various types I'd like to use dec_proxy I currently require creating a specialized instance of dec_proxy - it seems like a very messy and limited approach.

My question is: What is the correct way to pass such short-lived temporaries as non-const reference parameters?

like image 403
Xander Tulip Avatar asked Oct 05 '11 06:10

Xander Tulip


People also ask

Why can't you make a non const reference to a literal?

A non-const reference cannot point to a literal. You cannot bind a literal to a reference to non-const (because modifying the value of a literal is not an operation that makes sense) and only l-values can be bound to references to non-const.

Can you pass a non const to a const?

Converting between const and non-const For instance, you can pass non-const variables to a function that takes a const argument. The const-ness of the argument just means the function promises not to change it, whether or not you require that promise.

Does C support pass by constant reference?

C does not support references or passing by reference. You should use pointers instead and pass by address. Pass-by-value is efficient for primitive types, but does a shallow copy for structs. In C++ it makes a LOT of sense to pass objects by reference for efficiency.

What is non const reference?

I think this means that making a reference a "const" when it is referenced to a non const object does absolutely nothing. We may as well take that const keyword out when defining that reference. Not true. You may not modify the a non- const object through a const reference.


1 Answers

Taking Stephen's advice, you should look at the answer to How come a non-const reference cannot bind to a temporary object? and simply add a member function that returns a reference dec_proxy, e.g.:

dec_proxy &ref() { return *this; }

and call foo:

foo(
    dec_proxy<int>(i).ref(), 
    dec_proxy<double>(j).ref(), 
    dec_proxy<short>(k).ref());

I'm pretty sure that compiles.

like image 81
MSN Avatar answered Oct 29 '22 15:10

MSN