Note that there are some explanatory texts on larger screens.

plurals
  1. POBetter Way To Use C++ Named Parameter Idiom?
    text
    copied!<p>I've been developing a GUI library for Windows (as a personal side project, no aspirations of usefulness). For my main window class, I've set up a hierarchy of option classes (using the <a href="http://www.parashift.com/c++-faq-lite/named-parameter-idiom.html" rel="nofollow noreferrer">Named Parameter Idiom</a>), because some options are shared and others are specific to particular types of windows (like dialogs).</p> <p>The way the Named Parameter Idiom works, the functions of the parameter class have to return the object they're called on. The problem is that, in the hierarchy, each one has to be a <em>different</em> class -- the <code>createWindowOpts</code> class for standard windows, the <code>createDialogOpts</code> class for dialogs, and the like. I've dealt with that by making all the option classes templates. Here's an example:</p> <pre><code>template &lt;class T&gt; class _sharedWindowOpts: public detail::_baseCreateWindowOpts { public: /////////////////////////////////////////////////////////////// // No required parameters in this case. _sharedWindowOpts() { }; typedef T optType; // Commonly used options optType&amp; at(int x, int y) { mX=x; mY=y; return static_cast&lt;optType&amp;&gt;(*this); }; // Where to put the upper-left corner of the window; if not specified, the system sets it to a default position optType&amp; at(int x, int y, int width, int height) { mX=x; mY=y; mWidth=width; mHeight=height; return static_cast&lt;optType&amp;&gt;(*this); }; // Sets the position and size of the window in a single call optType&amp; background(HBRUSH b) { mBackground=b; return static_cast&lt;optType&amp;&gt;(*this); }; // Sets the default background to this brush optType&amp; background(INT_PTR b) { mBackground=HBRUSH(b+1); return static_cast&lt;optType&amp;&gt;(*this); }; // Sets the default background to one of the COLOR_* colors; defaults to COLOR_WINDOW optType&amp; cursor(HCURSOR c) { mCursor=c; return static_cast&lt;optType&amp;&gt;(*this); }; // Sets the default mouse cursor for this window; defaults to the standard arrow optType&amp; hidden() { mStyle&amp;=~WS_VISIBLE; return static_cast&lt;optType&amp;&gt;(*this); }; // Windows are visible by default optType&amp; icon(HICON iconLarge, HICON iconSmall=0) { mIcon=iconLarge; mSmallIcon=iconSmall; return static_cast&lt;optType&amp;&gt;(*this); }; // Specifies the icon, and optionally a small icon // ...Many others removed... }; template &lt;class T&gt; class _createWindowOpts: public _sharedWindowOpts&lt;T&gt; { public: /////////////////////////////////////////////////////////////// _createWindowOpts() { }; // These can't be used with child windows, or aren't needed optType&amp; menu(HMENU m) { mMenuOrId=m; return static_cast&lt;optType&amp;&gt;(*this); }; // Gives the window a menu optType&amp; owner(HWND hwnd) { mParentOrOwner=hwnd; return static_cast&lt;optType&amp;&gt;(*this); }; // Sets the optional parent/owner }; class createWindowOpts: public _createWindowOpts&lt;createWindowOpts&gt; { public: /////////////////////////////////////////////////////////////// createWindowOpts() { }; }; </code></pre> <p>It works, but as you can see, it requires a noticeable amount of extra work: a type-cast on the return type for each function, extra template classes, etcetera.</p> <p>My question is, is there an easier way to implement the Named Parameter Idiom in this case, one that doesn't require all the extra stuff?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload