Templates increase code size, a way around this ?
I like templates and even if I didn't I would still have to use them since ATL is mostly based on them.
But the problem I face (I think, please correct me if I'm wrong) is that whenever a template class is instantiated with a different parameter, all of its functions are "written out in full" by the compiler. This is usually fine, but the problem comes from the functions in the class which don't depend on the template parameters. They should not need to get get duplicated and unneccessarily increase the code size.
My concrete problem is that I have defined a templated "boiler-plate" windowed ActiveX object derived from about 15 ATL templates and a few of my own classes that does the basic window management, forwards the messages appropriately and does some other funky stuff.
The only reason I have to make this class templated is that otherwise I can't derive it from the basic ATL templates, don't have access to the required ATL variables (like m_bWindowOnly e.g.), can't call base functions (in only a very few of my functions) and can't expect ATL to call my overridden virtual functions.
Most of the overridden virtual functions don't require any template arguments, so having them in the templated class unfortunately duplicates them in the compiler-generated code and increases the size :/
What could I do ?
Re: Templates increase code size, a way around this ?
Quote:
Originally posted by Yves M
But the problem I face (I think, please correct me if I'm wrong) is that whenever a template class is instantiated with a different parameter, all of its functions are "written out in full" by the compiler.
AFAIK, only functions that are actually used get instantiated.
Re: Re: Templates increase code size, a way around this ?
Thanks for the help :)
Quote:
AFAIK, only functions that are actually used get instantiated.
Sure, but all the functions do get used ;) They are mostly overrides for the standard handling that ATL does, so they will get called.
Axter and Jeff:
Unfortunately most of the functions do depend on stuff provided by the base ATL classes. To use a simple description, here is what it looks like:
Code:
// An ATL class that provides the basic functionality
// I derive from about 15 of these
template <class Base>
class ATLBaseComObject
{
public:
HWND GetHwnd() {/*code*/}
HRESULT IOleObject_SetClientSite() {/*code*/}
// ...
};
// My "boiler-plate" implementation
// (has actually 5 template parameters)
template <class Base>
class BoilerPlate : public ATLBaseComObject<Base>
{
public:
// STDMETHOD stands for "virtual HRESULT __stdcall"
// This method does not need the template parameters
// But does need the base class functionality
STDMETHOD(Refresh)()
{
HWND hwnd = GetHwnd();
::RedrawWindow(hwnd, 0, 0, RDW_UPDATENOW);
return S_OK;
}
// This method needs the template parameter
STDMETHOD(IOleObject_SetClientSite)()
{
HRESULT hr = ATLBaseComObject<Base>::IOleObject_SetClientSite();
Refresh();
return hr;
}
};
class CFinal : public BoilerPlate<CFinal>
{
public:
STDMETHOD(SomeStuff)()
{
// Update the data and refresh the view
RefreshView();
}
};
Quote:
Simply put the methods that don't use the template parameter in the .cpp file.
This I don't understand :/ Do you mean to write it in Final.cpp ?That would defeat the point of the Boilerplate class :/