Find the template function address

Recently, I used WTL to write the Ribbon interface and found a pit.

First look at the code of WTL9.1

static void (CharFormat::*Getk_[])(IPropertyStore*) = 
{
    &CharFormat::Getk_Family, 
    &CharFormat::Getk_FontProperties_Size, 
    &CharFormat::Getk_MaskEffect<CFM_BOLD, CFE_BOLD, UI_PKEY_FontProperties_Bold>,
    &CharFormat::Getk_MaskEffect<CFM_ITALIC, CFE_ITALIC, UI_PKEY_FontProperties_Italic>,
    &CharFormat::Getk_MaskEffect<CFM_UNDERLINE, CFE_UNDERLINE, UI_PKEY_FontProperties_Underline>,
    &CharFormat::Getk_MaskEffect<CFM_STRIKEOUT, CFE_STRIKEOUT, UI_PKEY_FontProperties_Strikethrough>,
    &CharFormat::Getk_VerticalPositioning, 
    &CharFormat::Getk_Color<CFM_COLOR, UI_PKEY_FontProperties_ForegroundColor>, 
    &CharFormat::Getk_Color<CFM_BACKCOLOR, UI_PKEY_FontProperties_BackgroundColor>, 
    &CharFormat::Getk_ColorType<CFM_COLOR, CFE_AUTOCOLOR, UI_SWATCHCOLORTYPE_AUTOMATIC, UI_PKEY_FontProperties_ForegroundColorType>,
    &CharFormat::Getk_ColorType<CFM_BACKCOLOR, CFE_AUTOBACKCOLOR, UI_SWATCHCOLORTYPE_NOCOLOR, UI_PKEY_FontProperties_BackgroundColorType>,
};

Among them, Getk_MaskEffect is a template function, which is implemented as follows:

template <DWORD t_dwMask, DWORD t_dwEffects, REFPROPERTYKEY key>
void Getk_MaskEffect(IPropertyStore* pStore)
{
    if (SUCCEEDED(pStore->GetValue(key, &propvar)))
    {
        UIPropertyToUInt32(key, propvar, &uValue);
        if ((UI_FONTPROPERTIES)uValue != UI_FONTPROPERTIES_NOTAVAILABLE)
        {
            dwMask |= t_dwMask;
            dwEffects |= ((UI_FONTPROPERTIES) uValue == UI_FONTPROPERTIES_SET) ? t_dwEffects : 0;
        }
    }	
}

Then, the compilation fails in VS2017...

1>X:\WTL91_5321_Final\Include\atlribbon.h(422): error C2440: 'initializing': cannot convert from 'overloaded-function' to 'void (__thiscall WTL::RibbonUI::CharFormat::* )(IPropertyStore *)'

1>X:\WTL91_5321_Final\Include\atlribbon.h(422): note: None of the functions with this name in scope match the target type

Then searched according to the error prompt: Cannot take address of template function, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39018 , translate it: address conversion of template function, in two steps, first The first step is to transfer the materialization, and the second step is to transfer the target type. This is possible; it is not possible to directly transfer to the past!

Let's see how WTL10 solves this problem!

static void (CharFormat::*Getk_[])(IPropertyStore*) = 
{
    &CharFormat::Getk_Family, 
    &CharFormat::Getk_FontProperties_Size, 
    &CharFormat::Getk_MaskEffectBold,
    &CharFormat::Getk_MaskEffectItalic,
    &CharFormat::Getk_MaskEffectUnderline,
    &CharFormat::Getk_MaskEffectStrikeout,
    &CharFormat::Getk_VerticalPositioning,
    &CharFormat::Getk_Color, 
    &CharFormat::Getk_ColorBack, 
    &CharFormat::Getk_ColorType,
    &CharFormat::Getk_ColorTypeBack,
};

The original template function has been replaced with a normal function...

void Getk_MaskEffectBold(IPropertyStore* pStore)
{
    Getk_MaskEffectAll(pStore, CFM_BOLD, CFE_BOLD, UI_PKEY_FontProperties_Bold);
}

void Getk_MaskEffectItalic(IPropertyStore* pStore)
{
    Getk_MaskEffectAll(pStore, CFM_ITALIC, CFE_ITALIC, UI_PKEY_FontProperties_Italic);
}

void Getk_MaskEffectUnderline(IPropertyStore* pStore)
{
    Getk_MaskEffectAll(pStore, CFM_UNDERLINE, CFE_UNDERLINE, UI_PKEY_FontProperties_Underline);
}

void Getk_MaskEffectStrikeout(IPropertyStore* pStore)
{
    Getk_MaskEffectAll(pStore, CFM_STRIKEOUT, CFE_STRIKEOUT, UI_PKEY_FontProperties_Strikethrough);
}

void Getk_MaskEffectAll(IPropertyStore* pStore, DWORD _dwMask, DWORD _dwEffects, REFPROPERTYKEY key)
{
    if (SUCCEEDED(pStore->GetValue(key, &propvar)))
    {
        UIPropertyToUInt32(key, propvar, &uValue);
        if ((UI_FONTPROPERTIES)uValue != UI_FONTPROPERTIES_NOTAVAILABLE)
        {
            dwMask |= _dwMask;
            dwEffects |= ((UI_FONTPROPERTIES)uValue == UI_FONTPROPERTIES_SET) ? _dwEffects : 0;
        }
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324943630&siteId=291194637