Discussion:
Template classes with virtual member functions
(too old to reply)
Inbilla
2010-03-12 00:29:56 UTC
Permalink
Hi there,

This is a cross posting from the C++.lang.Moderated group, as I've
recently got a hunch that this problem may be visual studio
specific... So I'd like to hear what you have to say...

I'm trying to get the following code to work:

[begincode]

class ReferenceBase
{
public:
virtual ~ReferenceBase()
{
}

void MarkResolved(bool bResolved)
{
OnResolved();
}

virtual void OnResolved()
{
// Do nothing
}

};

template <class ReferrerType>
struct ReferrerTraits
{
typedef void (ReferrerType::*CallbackType)(ReferenceBase*
pkReference);

};

template <class ReferrerType, typename
ReferrerTraits<ReferrerType>::CallbackType ReferrerCallback>
class Reference : public ReferenceBase
{
virtual void OnResolved()
{
if (m_referrer)
{
(m_referrer->*ReferrerCallback)(this);
}
}

void SetReferrer(ReferrerType* referrer)
{
m_referrer = referrer;
}

private:
ReferrerType* m_referrer;

};

class Referrer
{
void OnReferenceResolved(Reference* pReference)
{
// Do something
}

typedef Reference<Referrer, &Referrer::OnReferenceResolved>
ObjectReference;
ObjectReference m_objectReference;

}

[endcode]

Ok, so I am basically trying to setup a set of classes whereby I have
a reference to something that needs resolving. Every now and again, an
application process will resolve these references and call
"MarkResolved" on the ones it resolves. This should in turn call
OnResolved.

The idea is that the objects that own these references will be able to
listen in to when these references are resolved via a templated
version of the reference class and a compiletime assigned callback
function.

The trouble is, I get the following warning whilst compiling these
classes:
warning C4505:
'Reference<ReferrerType,ReferrerCallback>::OnResolved' : unreferenced
local function has been removed

These warnings come up when attempting to compile any other .cpp file
that includes Referrer.h.

Now, as far as I can see, OnResolved is clearly referenced by the
MarkResolved function, so it should never be removed under any
circumstance?

What am I missing? What am I doing wrong?
If you have a link to something in the standard about what I'm doing
and why its not good, I'd love to see it!

I'm compiling under VC90. But the code needs to support GCC and other
compilers too

Thanks for your help in advance!

Josh
Stephan T. Lavavej [MSFT]
2010-03-12 03:47:04 UTC
Permalink
That doesn't compile. Referrer::OnReferenceResolved() takes Reference *,
but Reference is a template. After replacing that with ReferenceBase *,
which you presumably meant, and fixing other small things, I got code that
compiled cleanly instead of triggering C4505.

The best repros are those that take the form of:

C:\Temp>type meow.cpp
[STUFF]

C:\Temp>cl /EHsc /nologo /W4 /c meow.cpp
[BOOM]

(Adjust as necessary for different compiler options or to actually run the
program.)

That way, everyone can see your exact code, and the exact way you compiled
it. Otherwise, you're going to waste the time of people who were trying to
help you.

Stephan T. Lavavej
Visual C++ Libraries Developer
Post by Inbilla
Hi there,
This is a cross posting from the C++.lang.Moderated group, as I've
recently got a hunch that this problem may be visual studio
specific... So I'd like to hear what you have to say...
[begincode]
class ReferenceBase
{
virtual ~ReferenceBase()
{
}
void MarkResolved(bool bResolved)
{
OnResolved();
}
virtual void OnResolved()
{
// Do nothing
}
};
template <class ReferrerType>
struct ReferrerTraits
{
typedef void (ReferrerType::*CallbackType)(ReferenceBase*
pkReference);
};
template <class ReferrerType, typename
ReferrerTraits<ReferrerType>::CallbackType ReferrerCallback>
class Reference : public ReferenceBase
{
virtual void OnResolved()
{
if (m_referrer)
{
(m_referrer->*ReferrerCallback)(this);
}
}
void SetReferrer(ReferrerType* referrer)
{
m_referrer = referrer;
}
ReferrerType* m_referrer;
};
class Referrer
{
void OnReferenceResolved(Reference* pReference)
{
// Do something
}
typedef Reference<Referrer, &Referrer::OnReferenceResolved>
ObjectReference;
ObjectReference m_objectReference;
}
[endcode]
Ok, so I am basically trying to setup a set of classes whereby I have
a reference to something that needs resolving. Every now and again, an
application process will resolve these references and call
"MarkResolved" on the ones it resolves. This should in turn call
OnResolved.
The idea is that the objects that own these references will be able to
listen in to when these references are resolved via a templated
version of the reference class and a compiletime assigned callback
function.
The trouble is, I get the following warning whilst compiling these
'Reference<ReferrerType,ReferrerCallback>::OnResolved' : unreferenced
local function has been removed
These warnings come up when attempting to compile any other .cpp file
that includes Referrer.h.
Now, as far as I can see, OnResolved is clearly referenced by the
MarkResolved function, so it should never be removed under any
circumstance?
What am I missing? What am I doing wrong?
If you have a link to something in the standard about what I'm doing
and why its not good, I'd love to see it!
I'm compiling under VC90. But the code needs to support GCC and other
compilers too
Thanks for your help in advance!
Josh
Loading...