こんにちは、高木です。
今回はそんなに目新しい話題ではありません。前回は割愛したgeometry_managerクラスの基本コマンド(関数呼出し演算子)を多重定義して、もう少し充実させていきます。
前回は長くなるので割愛したメンバー関数を今回は作り込んでいきます。地味な作業ですが必要ですからね。
まずはおさらいとして、geometry_managerクラスの基本コマンドを実現するメンバー関数(関数呼出し演算子)を見ていきましょう。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// 基本コマンド int operator()(std::initializer_list<window> windows, std::initializer_list<tcl::obj> options) const { std::vector<Tcl_Obj*> args{ this->type_.get() }; Tcl_Interp* interp = nullptr; std::for_each(windows.begin(), windows.end(), [&args, &interp](auto w) { // 各ウィンドウが所属しているインタープリターの一致判定 if (interp == nullptr) interp = w.get().interpreter().get(); else if (interp != w.get().interpreter().get()) throw std::runtime_error("異なるインタープリターに所属するウィジェットが混在している"); args.push_back(w.get().path().get()); }); std::for_each(options.begin(), options.end(), [&args](auto option) { args.push_back(option.get()); }); return tcl::interpreter(interp).evaluate(args); } |
これは前回掲載したコードの抜粋です。このメンバー関数では、1個以上のウィジェットと0個以上のオプションを指定する前提になっています。
しかし、実際にはウィジェットは1個だけ指定することが結構ありますし、オプション無しの場合も少なくありません。それらにも対応した多重定義を行って利便性を向上していきます。
多重定義したコードは次のようになります。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// オプション無し int operator()(std::initializer_list<window> windows) const { return operator()(windows, {}); } // ウィジェト1つ、オプションあり int operator()(const window& w, std::initializer_list<tcl::obj> options) const { std::vector<Tcl_Obj*> args{ this->type_.get(), w.get().path().get() }; Tcl_Interp* interp = w.get().interpreter().get(); std::for_each(options.begin(), options.end(), [&args](auto option) { args.push_back(option.get()); }); return tcl::interpreter(interp).evaluate(args); } // ウィジェット1つ、オプション無し int operator()(const window& w) const { return operator()(w, {}); } |
全部個別に実装すると保守性が悪くなります。ウィジェットが1つだけの場合は特別扱いした方がよさそうだと考えて、このようにしました。
次回は、これらのメンバー関数をもう少し一般化して、configureコマンドなどにも対応できるようにしていきたいと考えています。