C ++の「概念」

すべての良い一日。



これは、C ++の概念のトピックに関するStraustrupの出版物の影響を受けて発明され、書かれました。

私はかつて、非標準のC ++関数/メソッドが、特定のメソッドセットを引数として持つオブジェクトを受け入れるようにすることは珍しいと感じていました。

void fn(VectorWrapper<int> x) { for (size_t i = 0; i < x.size(); ++i) { doSomething(x[i]); } } ::std::vector<int> sv; QList<int> qv; OtherSuperVector<int> ov; fn(sv); fn(qv); fn(ov);
      
      





基本クラスからの継承を使用せずにこれを行うには。

これを行うには、カットの下で読んでください。



私が遭遇した主な困難は、テンプレート引数(格納された値の型)を1つしか持たないVectorWrapper型を作成することでしたが、特定のメソッドセットを持つものから作成できました。 私の例では、これらは演算子[]とサイズ()です。 しばらく考えてから、C ++ 11標準の機能を使用する設計が生まれました。



 template <typename T> class VectorWrapper { public: template <typename C> VectorWrapper(C& container) : _getter([&container](size_t i) -> T& { return container[i]; }), _sizeGetter([&container]() -> size_t { return container.size(); }) { } T& operator[](size_t i) { return _getter(i); } size_t size() { return _sizeGetter(); } private: ::std::function<T&(size_t) > _getter; ::std::function<size_t() > _sizeGetter; };
      
      







その結果、このクラスのオブジェクトを作成するとき、コンストラクターに渡されたオブジェクトはラムダによってキャプチャされ、クラス自体のメソッドは格納されたラムダを呼び出し、キャプチャされたオブジェクトのメソッドをプルします。

さて、このラッパーでは、size()およびoperator []メソッドで必要なものをラップできます。



現実のどこかで使用できるかどうかはわかりませんが、問題を解決しました。この不名誉に至る前に、この方法で解決したかったのです。 そのようなクラスをどこでも使用すると、パフォーマンスが大幅に低下する可能性があるという疑いもあります。



まあ、純粋に好奇心から、ホーカーの問題は、ラムダとC ++ 11の助けを借りずにこれを行うことができるかどうかです?



All Articles