tags:

views:

695

answers:

6

I have this code:

CCalcArchive::CCalcArchive() : m_calcMap()
{
}

m_calcMap is defined as this:

typedef CTypedPtrMap<CMapStringToPtr, CString, CCalculation*> CCalcMap;
CCalcMap& m_calcMap;

When I compile in Visual Studio 2008, I get this error:

error C2440: 'initializing' : cannot convert from 'int' to 'CCalcArchive::CCalcMap &'

I don't even understand where it gets the "int" error from, and also why this doesn't work? It feels like I'm actually having some sort of syntax error, but isn't this how member initialization lists are supposed to be used? Also, AFAIK, the MFC class CTypedPtrMap has no constructor taking arguments.

+2  A: 

Unless I'm missing something, since it is a reference, it needs to be initialized to point to something. Reference variables, by definition, can't be initialized to NULL.

As far as the int, I don't know why it is saying that.

Torlack
Jeffrey Martinez
+3  A: 

I'm not sure where it's getting the int from, but you must initialize all references in the initializer list. m_calcMap is declared as a reference, and so it must be initialized to refer to some instance of a CCalcMap object - you can't leave it uninitialized. If there's no way for you to pass the referred-to object into the constructor, or there's a possibility that you need it to not refer to an object, then use a pointer instead of a reference.

Adam Rosenfield
A: 

It's a common MO for C++ compilers, when they can't figure out what a type is, to spit out an error message and assume that the user meant 'int' in order to be able to continue (...and generate even more error messages ;-)

You do need to initialize all references in a class in your constructors, though.

Ferruccio
+1  A: 

The int is coming from the fact that CTypedPtrMap has a constructor that takes an int argument that is defaulted to 10.

The real problem that you're running into is that the m_calcMap reference initalization you have there is trying to default construct a temporary CTypedPtrMap object to bind the reference to. However, only const references can be bound to temporary objects. No doubt the error message is not very informative.

But even if the m_calcMap member were a const refernce, you'd still have a problem binding it to a temporary. in this case, the MSVC 2008 compiler gives a pretty clear warning:

mfctest.cpp(72) : warning C4413: '' : reference member is initialized to a temporary 
                                       that doesn't persist after the constructor exits
Michael Burr
A: 

Ah, yes my idea was that I intended to run its constructor in the initializer list, and thus have the object be constructed at all times. It's getting more clear now after especially Mike B's reply and now makes perfect sense that the constructed object would immediately be destructed after going out of scope. That's what I never considered first. :S I thought that was OK with references, along with initializing it with a reference to an existing object.

Jonas
A: 

What about

CCalcArchive::CCalcArchive() : m_calcMap( CCalcMap(/*arguments or whatever*/) )
{
  // ...
}

Is it possible to bind just created temporary into the reference like this? Will that temporary persist for the CCalcArchive instance lifetime...?

pj00