Как пишет Атес в своем ответе, вам все еще нужно написать обертки для членов CDownloader, поэтому конечный результат, вероятно, будет столь же многословным и более сложным для понимания, чем простой способ. Например, это может быть возможность (предупреждение: непроверенный код впереди):
BOOL Get(const CDownloader &Loader, const CString& Name, int* Result)
{
return Loader.getInteger(Name, Result);
}
BOOL Get(const CDownloader &Loader, const CString& Name, CImage* Result)
{
return Loader.getImage(Name, SomeDefaultValueForNeedCache, Result);
}
BOOL Get(const CDownloader &Loader, const CString& Name, CFont* Result)
{
return Loader.getFont(Name, Result);
}
template<class T>
BOOL Download(const CDownloader &Loader, bool Flag, T* Result)
{
if (Flag) {
// first try the "name_1"
if ( Get(Loader, "name_1", Result) ) return TRUE;
}
// if "name_1" fails or disabled by flag, try "name_2"
return Get (Loader, "name_2", Result);
}
Пытаясь быть «умнее», можно попытаться сделать boost :: fusion :: map для методов получения, проиндексированных по типу «getted»:
fusion::map<
fusion::pair<int, boost::function<BOOL(const CDownloader&, int*)>,
fusion::pair<CImage, boost::function<BOOL(const CDownloader&, CImage*)>,
fusion::pair<CFont, boost::function<BOOL(const CDownloader&, CFont*)>
>
GetterMap = fusion::make_map(
fusion::make_pair<int>(bind(&CDownloader::getInteger, _1, _2)),
fusion::make_pair<CImage>(&CDownloader::getImage, _1, SomeDefaultValueForNeedCache, _2),
fusion::make_pair<CFont>(&CDownloader::getFont, _1, _2)
);
template<class T>
BOOL Download(const CDownloader &Loader, bool Flag, T* Result)
{
if (Flag) {
// first try the "name_1"
if ( fusion::at<T>(GetterMap)(Loader, "name_1", Result) ) return TRUE;
}
// if "name_1" fails or disabled by flag, try "name_2"
return fusion::at<T>(GetterMap)(Loader, "name_2", Result);
}
Как видите, выигрыш по сравнению с простым способом не очевиден.