È questo davvero l'unico modo per ottenere l'indirizzo corretto per una funzione di esempio:c'è un modo migliore per selezionare il sovraccarico del metodo corretto?
typedef CBitmap * (CDC::* SelectObjectBitmap)(CBitmap*);
SelectObjectBitmap pmf = (SelectObjectBitmap)&CDC::SelectObject;
In primo luogo, si deve creare un typedef, e quindi si deve usare quello per forzare il compilatore per selezionare la corretta sovraccarico metodo quando si prende il suo indirizzo?
non c'è una sintassi che è più naturale e autosufficiente, come ad esempio:
SelecdtObjectBitmap pmf = &CDC::SelectObject(CBitmap*);
Io uso ScopeGuard spesso nel mio codice. E un ovvio uso è assicurare che qualsiasi oggetto CDC temporaneo venga prima selezionato in un dato DC, poi rimosso all'uscita dallo scope, rendendo il mio codice privo di perdite anche in circostanze eccezionali - e contemporaneamente ripulendo il codice scritto (stupidi percorsi di uscita multipli e provare/catch e così via per cercare di gestire la rimozione di qualsiasi oggetto selezionato da un dato CDC).
Così un esempio più completo di quello che attualmente sono costretto a fare assomiglia:
// get our client rect
CRect rcClient;
GetClientRect(rcClient);
// get the real DC we're drawing on
PAINTSTRUCT ps;
CDC * pDrawContext = BeginPaint(&ps);
// create a drawing buffer
CBitmap canvas;
canvas.CreateCompatibleBitmap(pDrawContext, rcClient.Width(), rcClient.Height());
CDC memdc;
memdc.CreateCompatibleDC(pDrawContext);
//*** HERE'S THE LINE THAT REALLY USES THE TYPEDEF WHICH i WISH TO ELIMINATE ***//
ScopeGuard guard_canvas = MakeObjGuard(memdc, (SelectObjectBitmap)&CDC::SelectObject, memdc.SelectObject(&canvas));
// copy the image to screen
pDrawContext->BitBlt(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), &memdc, rcClient.left, rcClient.top, SRCCOPY);
// display updated
EndPaint(&ps);
E 'sempre mi ha colpito come goffo come l'inferno che ho bisogno di typedef ogni funzione sovraccaricata che desidero prendere la indirizzo di.
Quindi ... c'è un modo migliore ?!
EDIT: Sulla base delle risposte persone hanno in dotazione, credo di avere una soluzione al mio bisogno di fondo: cioè di avere una sintassi più naturale per MakeGuard che deduce la corretta sostituzione SelezionaOggetto per me:
template <class GDIObj>
ObjScopeGuardImpl1<CDC, GDIObj*(CDC::*)(GDIObj*), GDIObj*> MakeSelectObjectGuard(CDC & dc, GDIObj * pGDIObj)
{
return ObjScopeGuardImpl1<CDC, GDIObj*(CDC::*)(GDIObj*), GDIObj*>::MakeObjGuard(dc, (GDIObj*(CDC::*)(GDIObj*))&CDC::SelectObject, dc.SelectObject(pGDIObj));
}
che rende la mia sopra modifica del codice a:
ScopeGuard guard_canvas = MakeSelectObjectGuard(memdc, &canvas);
///////////////////////////////// /////////////////////////
Per coloro che potrebbero cercare qui per una versione non MFC della stessa cosa:
//////////////////////////////////////////////////////////////////////////
//
// AutoSelectGDIObject
// selects a given HGDIOBJ into a given HDC,
// and automatically reverses the operation at scope exit
//
// AKA:
// "Tired of tripping over the same stupid code year after year"
//
// Example 1:
// CFont f;
// f.CreateIndirect(&lf);
// AutoSelectGDIObject select_font(*pDC, f);
//
// Example 2:
// HFONT hf = ::CreateFontIndirect(&lf);
// AutoSelectGDIObject select_font(hdc, hf);
//
// NOTE:
// Do NOT use this with an HREGION. Those don't need to be swapped with what's in the DC.
//////////////////////////////////////////////////////////////////////////
class AutoSelectGDIObject
{
public:
AutoSelectGDIObject(HDC hdc, HGDIOBJ gdiobj)
: m_hdc(hdc)
, m_gdiobj(gdiobj)
, m_oldobj(::SelectObject(m_hdc, gdiobj))
{
ASSERT(m_oldobj != m_gdiobj);
}
~AutoSelectGDIObject()
{
VERIFY(m_gdiobj == ::SelectObject(m_hdc, m_oldobj));
}
private:
const HDC m_hdc;
const HGDIOBJ m_gdiobj;
const HGDIOBJ m_oldobj;
};
//////////////////////// //////////////////////////////////
Grazie a tutti coloro che hanno risposto & commentato! : D
Puoi farlo, ma sicuramente non sarà bello: praticamente finirai per inserire il corpo del typedef dove attualmente usi il nome typedef. – James
Spero che non sia questo CBitmap: http://thedailywtf.com/Articles/The-cbitmap.aspx –