When writing a C ++ class template, you sometimes want the template parameters to meet certain requirements, that is, constraints. For example, a template type parameter T must be derived from the base class TBase.
The where keyword can be used to specify constraints in the C # Generic Model, while the C ++ template lacks similar constraints.
C ++ 0x introduces some new features, and the C ++ standard library has been improved and expanded. There are two good references:
Explicating the new C ++ standard (C ++ 0x), and its implementation in VC10Standard C ++ Library changes in Visual C ++ 2010
With these new features, you can specify some constraints for template parameters.
For example, in a template in WTL, some template parameters must be inherited (directly or indirectly) from the specified class before being compiled, such as CApplicationT:
template<typename T, typename TMainWindow, bool bInitializeCom = false>
class CApplicationT :
public CAppModule
{public:
//Call this method in the application's entry point[_tWinMain(...)]
int WinMain(HINSTANCE hInstance,LPTSTR lpCmdLine,int nCmdShow)
{ //Ensure that TMainWindow is derived from CWindow
static_assert(std::is_base_of<CWindow,TMainWindow>::value,
"TMainWindow needs to be CWindow based.");
UNREFERENCED_PARAMETER(lpCmdLine);
T* pT = static_cast<T*>(this);
//......
int nRet = 0;
{ CMessageLoop msgLoop;
AddMessageLoop(&msgLoop);
TMainWindow wndMain;
_g_hMainWindow = wndMain.Create(NULL,CWindow::rcDefault);
if(_g_hMainWindow == NULL)
{ ATLTRACE(_T("Failed to create Main window!\n")); return 0;
}
wndMain.ShowWindow(nCmdShow);
wndMain.UpdateWindow();
wndMain.CenterWindow();
//......
This template class has a type parameter TMainWindow, which calls some member functions of this class in the Code, such as Create (...), ShowWindow () and so on. However, these member functions are actually CWindow class member functions. That is to say, the TMainWindow class must inherit (directly or indirectly) from the CWindow class to pass the correct compilation during template instantiation.
Otherwise, if TMainWindow is not a CWindow derived class, compile the following code:
CApplication<CTestWindow> g_MainApp;
The compiler prompts the following error:
e:\coding\mywtllib\wtlapp.h(56): error C2039: 'Create' : is not a member of 'CTestWindow'
d:\cpp\wtl\wtlapp\win7shell\mainapp.cpp(6) : see declaration of 'CTestWindow'
E: \ coding \ mywtllib \ wtlapp. h (62): error C2039: 'showwindow': is not a member of 'ctestwindow'
D: \ cpp \ wtl \ wtlapp \ win7shell \ mainapp. cpp (6): see declaration of 'ctestwindow'
This compilation error is not intuitive enough. When some of the less common member functions are encountered, especially the template code written by others, and the document description is missing, it is difficult to figure out what conditions should be met for TMainWindow to compile and pass.
Fortunately, we can use some new features of C ++ 0x to explicitly specify that TMainWindow must be inherited from the CWindow class (either directly or indirectly ), the method is to add a static asserted code in the CApplicationT template implementation code:
template<typename T, typename TMainWindow, bool bInitializeCom = false>
class CApplicationT :
public CAppModule
{public:
//Call this method in the application's entry point[_tWinMain(...)]
int WinMain(HINSTANCE hInstance,LPTSTR lpCmdLine,int nCmdShow)
{ //Ensure that TMainWindow is derived from CWindow
static_assert(std::is_base_of<CWindow,TMainWindow>::value,
"TMainWindow needs to be CWindow based.");
UNREFERENCED_PARAMETER(lpCmdLine);
T* pT = static_cast<T*>(this);
//......
In this way, when TMainWindow does not meet the conditions, the compiler will prompt the following error:
E: \ coding \ mywtllib \ wtlapp. h (25): error C2338: TMainWindow needs to be CWindow based.
In this way, the cause of the error is much clearer.
When Using std: is_base_of <>, you need to add the header file "# include <type_traits>"