c++ - 使用 C++ 命名参数习语的更好方法?

标签 c++ named-parameters

我一直在为 Windows 开发一个 GUI 库(作为个人的副项目,没有实用的愿望)。对于我的主窗口类,我设置了选项类的层次结构(使用 Named Parameter Idiom ),因为一些选项是共享的,而其他选项特定于特定类型的窗口(如对话框)。

命名参数习语的工作方式是,参数类的函数必须返回调用它们的对象。问题是,在层次结构中,每个类都必须是一个不同类 -- 标准窗口的 createWindowOpts 类,createDialogOpts 类用于对话框等。我通过制作所有选项类模板来处理这个问题。这是一个例子:

template <class T>
class _sharedWindowOpts: public detail::_baseCreateWindowOpts {
    public: ///////////////////////////////////////////////////////////////
    // No required parameters in this case.
    _sharedWindowOpts() { };

    typedef T optType;

    // Commonly used options
    optType& at(int x, int y) { mX=x; mY=y; return static_cast<optType&>(*this); }; // Where to put the upper-left corner of the window; if not specified, the system sets it to a default position
    optType& at(int x, int y, int width, int height) { mX=x; mY=y; mWidth=width; mHeight=height; return static_cast<optType&>(*this); }; // Sets the position and size of the window in a single call
    optType& background(HBRUSH b) { mBackground=b; return static_cast<optType&>(*this); }; // Sets the default background to this brush
    optType& background(INT_PTR b) { mBackground=HBRUSH(b+1); return static_cast<optType&>(*this); }; // Sets the default background to one of the COLOR_* colors; defaults to COLOR_WINDOW
    optType& cursor(HCURSOR c) { mCursor=c; return static_cast<optType&>(*this); }; // Sets the default mouse cursor for this window; defaults to the standard arrow
    optType& hidden() { mStyle&=~WS_VISIBLE; return static_cast<optType&>(*this); }; // Windows are visible by default
    optType& icon(HICON iconLarge, HICON iconSmall=0) { mIcon=iconLarge; mSmallIcon=iconSmall; return static_cast<optType&>(*this); }; // Specifies the icon, and optionally a small icon
    // ...Many others removed...
};

template <class T>
class _createWindowOpts: public _sharedWindowOpts<T> {
    public: ///////////////////////////////////////////////////////////////
    _createWindowOpts() { };

    // These can't be used with child windows, or aren't needed
    optType& menu(HMENU m) { mMenuOrId=m; return static_cast<optType&>(*this); }; // Gives the window a menu
    optType& owner(HWND hwnd) { mParentOrOwner=hwnd; return static_cast<optType&>(*this); }; // Sets the optional parent/owner
};

class createWindowOpts: public _createWindowOpts<createWindowOpts> {
    public: ///////////////////////////////////////////////////////////////
    createWindowOpts() { };
};

它有效,但如您所见,它需要大量额外工作:对每个函数的返回类型进行类型转换、额外的模板类等。

我的问题是,在这种情况下,是否有一种更简单的方法来实现命名参数习语,一种不需要所有额外东西的方法?

最佳答案

也许不是您想听到的,但我个人认为在库代码中(或多或少)对客户端隐藏很多丑陋的类型转换和模板参数是可以的只要 它是安全的并且 使客户的生活更轻松。库代码的美妙之处不在于代码本身,而在于它使客户能够编写的代码。以STL为例。

我还开发了一个小型 GUI 库作为个人项目,与您有着基本相同的愿望,其中的一些代码变得非常难看,但最终它允许我编写漂亮的客户端代码(至少在我(可能是变态的)眼中),恕我直言,这才是最重要的。

关于c++ - 使用 C++ 命名参数习语的更好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/210939/

相关文章:

Swift:如何解决下标歧义。命名下标?

c++ - C 中用 1 替换 0 的宏

c++ - 阻止 sqlite 步骤,直到数据库不再繁忙

dart - 如何向 Dart 类添加 getter,并在其构造函数上使用命名参数?

f# - 您如何在 F# 或任何函数式语言中对第二个(或第三个、第四个、...)参数进行 curry?

lambda - Kotlin:命名 lambda 参数的用途是什么?

c++ - 取消分配数组中的项目

c++ - 打印使用 C++ 中的新方法制作的二维数组

c++ - Boost vector 与 STL vector

c++ - 升压参数 : named template argument in combination with CRTP