Я не знаю, влюблен ли я в этот ответ, но есть возможность с использованием вывода аргументов шаблона. ПРИМЕЧАНИЕ У меня нет моего компилятора, завтра я проверю его дважды, если кто-то еще не захочет его обернуть.
class sharedWindowOpts
{
public:
sharedWindowOpts() {};
// Commonly used options
template <class optType>
static optType& at(int x, int y, optType& opts) { opts.mX=x; opts.mY=y; return opts; };
template <class optType>
static optType& background(HBRUSH b, optType& opts) { opts.mBackground=b; return opts; };
// etc...
}
class createWindowOpts : public sharedWindowOpts
{
public:
createWindowOpts() : sharedwindowOpts() {};
// These can't be used with child windows, or aren't needed
template <class optType>
static optType& menu(HMENU m, optType& opts) { opts.mMenuOrId=m; return opts; };
template <class optType>
static optType& owner(HWND hwnd, optType& opts) { opts.mParentOrOwner=hwnd; return opts; };
}
Тогда вы бы назвали CreateWindow следующим образом:
CreateWindow( createWindowOpts::owner(hwnd,
createWindowOpts::at(0, 100, // can use createWindowOpts because it doesn't hide sharedWindowsOpts::at
createWindowOpts::menu(hmenu, createWindowOpts() ) ) ) );
Несносные вещи об этом, конечно, должны использовать статический метод, вызывающий синтаксис и все лишние скобки. Если вы замените статические функции-члены функциями, не являющимися членами, это можно устранить. Тем не менее, он избегает приведения типов и дополнительных шаблонных классов.
Лично я предпочел бы иметь нечетный код в библиотеке, как в вашем методе, чем везде, где используется библиотека, как в моем.