开发者

Why does the C++ compiler generate a temporary here?

The following class is intended to monitor the changing state of another process; its constructor sets up const references to facilitate access to the relevant variables. Here's The ctor code:

template<typename FZYRSRC>
struct MergeableHeight: public FzyQty<FZYRSRC>
{
MergeableHeight( 
    const DDBuffer& me, const DDBuffer& neighbor, Orientation ori, bool useV =false)
: iP(me[PEAK_V].index()), iNP(neighbor[PEAK_V].index()),
  facingNeighbor(iP < iNP ? RIGHT_V : LEFT_V),  //vertex pointing to neighbor
  facingMe(iP < iNP ? LEFT_V : RIGHT_V),        //neighbor's vertex pointing to me
  iMyEdge(edgeBar(me,facingNeighbor)), iNeighborEdge(edgeBar(neighbor,facingMe)),
  myEdgeVal(me[facingNeighbor].datum()), neighborEdgeVal(neighbor[facingMe].datum()),
  myPeakVal(me[PEAK_V].datum()), useVolatility(useV),o(ori)             
{} 

 //member functions etc.
 private:
      virtual MergeableHeight* clone()const {return new MergeableHeight(*this);}
const int &iP, &iNP;
const PeakVertex facingNeighbor, facingMe; //PeakVertex is Enum {LEFT_V,PEAK_V,RIGHT_V} 
const int &iMyEdge, &iNeighborEdge;
const double &myEdgeVal, &neighborEdgeVal, &myPeakVal;
const Orientation o;
bool useVolatility;
  };

The class data members of interest are the two const int references iMyEdge and iNeighborEdge, initialized as

  iMyEdge(edgeBar(me,facingNeighbor)), iNeighborEdge(edgeBar(neighbor,facingMe)),

and the 3 const float references myEdgeVal, neighborEdgeVal, myPeakVal, initialized as

  myEdgeVal(me[facingNeighbor].datum()), 
  neighborEdgeVal(neighbor[facingMe].datum()),
  my开发者_JAVA技巧PeakVal(me[PEAK_V].datum()),

In the former case (the ints) the references work as expected. In the floats case, the compiler gives the message

"warning C4413: 'MergeableHeight::myEdgeVal' : reference member is initialized to a temporary that doesn't persist after the constructor exits," and similarly for the other two floats.

The user-defined DDBuffer type encapsulates a vector with a fixed number of DataDescriptors -- another user-defined type. DataDescriptor provides the member function datum(),

const float& datum()const {return _datum;}

while DDBuffer provides the [] operator,

const DatumDescriptor& operator[](int i)const {return buffer.at(i);}
DatumDescriptor& operator[](int i) {return buffer.at(i);} //const & non-const versions

Since everthing returns references, why on earth is a temporary being created here? In particular, the whole point is that the state variables should reflect the actual values in the references passed to the ctor, so I certainly wouldn't want a temporary created even if it was to remain in scope.

What am I missing??


datum() returns a const float& and your variable is a const double&. You cannot convert one to the other, hence the temporary.


myEdgeVal is a reference to the data stored in me which is passed to the constructor. As me is itself a const reference, it could be a temporary variable. If it is, then myEdgeVal would be a reference to something inside an object that's destroyed after the constructor completes.

How do you construct the MergeableHeight object in your code?

Also, as all of those member int/double variables are constant, there is no need to make them references.


Sure, me is a ref-to-const, and so is the result of me[facingNeighbor].datum().

However, the latter is a const float& and you're trying to bind it to a const double&, requiring a conversion. This produces a temporary, and it's one that exists only in the scope of the constructor.

Though its lifetime can be extended in higher stack frames (by binding to ref-to-const, as you know) it cannot magically be brought into lower stack frames.


Consider:

int foo();
const int& x = foo(); // valid; the result of foo() may exist as long as x does

But:

const int& foo() {
   return 5;          // not valid; returning reference to local variable
}

int x        = foo();
const int& y = foo(); // same issue.
                      // the `5` simply doesn't exist; its stack frame is gone.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜