こんにちは、高木です。
前回やり残してしまったgridderのサブコマンドを今回は実装してしまいましょう。残っているのは次の4つです。
- bbox
- location
- remove
- size
まずはbboxからです。
| 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |     std::span<Tcl_Obj*> bbox(const window& w) const     {       if (sub_command(u8"bbox", w) != TCL_OK)         return {};       auto interp = w.get().interpreter().get();       auto r = Tcl_GetObjResult(interp);       int objc;       Tcl_Obj** objv;       Tcl_ListObjGetElements(interp, r, &objc, &objv);       return { objv + 0, objv + objc };     }     int bbox(const window& w, std::initializer_list<tcl::obj> options) const     {       return sub_command(u8"bbox", w, options);     } | 
std::spanを返す最初の形式はslavesメンバー関数とほとんど同じです。下請けメンバー関数を作ってまとめられるので、今回は安直なコピペで対応したいと思います。
次はlocationです。
| 0 1 2 3 4 5 6 7 8 |     tcl::obj location(const window& w, int x, int y) const     {       if (sub_command(u8"locatione", w, { x, y }) != TCL_OK)         return {};       auto interp = w.get().interpreter().get();       return Tcl_GetObjResult(interp);     } | 
結果は整数値になるので、tcl::obj型ではなくint型にしてもよかったのですが、エラー発生時に例外を送出するしかなくなるので、いったんtcl::obj型を返すことにしました。エラー発生時は空の値を返します。
次はremoveです。
| 0 1 2 3 4 5 6 7 8 9 10 |     int remove(const window& w) const     {       return sub_command(u"remove", w);     }     int remove(std::initializer_list<window> windows) const     {       return sub_command(u"remove", windows);     } | 
initalizer_listで渡すものだけでもいいのですが、単独のウィジェットを指定するケースが結構あると思うので、専用のメンバー関数を用意しました。
最後はsizeです。sizeメンバー関数が返す値のために、次のような構造体を用意することにします。
| 0 1 2 3 4 5 6 7 8 9 | namespace tk {   struct size   {     int width;     int height;   }; } | 
この構造体は汎用的なものですので、今回に限らずいろいろ使っていけると思います。
準備ができたところで実際のsizeメンバー関数を実装していきます。
| 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |     tk::size size(const window& container) const     {       if (sub_command(u8"size", container) != TCL_OK)         return { -1, -1 };       auto interp = container.get().interpreter().get();       auto r = Tcl_GetObjResult(interp);       int objc;       Tcl_Obj** objv;       if (Tcl_ListObjGetElements(interp, r, &objc, &objv) != TCL_OK)         return { -1, -1 };       if (objc != 2)         return { -1, -1 };       return { tcl::obj(objv[0]).get_int().value_or(-1), tcl::obj(objv[1]).get_int().value_or(-1) };     } | 
たったこれだけのことなのにちょっと煩雑になってしまいました。まだまだ改善の余地がありそうです。
なかなか完璧にはほど遠いですが、これでgridderクラスが一通り完成しました。

![[迷信] freeにNULLを渡すとクラッシュする](https://www.kijineko.co.jp/wp-content/uploads/2021/06/4905202_s.jpg)
![[迷信] 一重引用符の中には一文字しか書けない](https://www.kijineko.co.jp/wp-content/uploads/2021/06/4842077_s.jpg)



