いくつかの大規模なプロジェクトの一環として、ブロック内の要素の値が定義済みの初期化子の値から変更された場合にのみブロックを動的に割り当てるマトリックス テンプレート クラスの開発に取り組んでいます。このクラスはかなり複雑な数学で使用されるため、インターフェイスをできるだけシンプルで直感的なものにしようとしています。get(row, col) および set(element) メソッドを使用する代わりに、 operator(row, col) を使用して参照によって行列要素にアクセスできるようにしたいと考えていました。
しかし、割り当ての動作により、set と get のアクションが異なる必要があり、初期化子の値に対して設定されている値をテストする必要があるため、これは問題になりました。これは参照を返すだけではできないため、参照を含み、正しいデータ型に変換できるヘルパー クラスを作成し、それを返しました。これはインターフェースの構造です:
template <class T>
class Container{
public:
// Element class which contains a reference to a data element
class Element{
public:
// Constructor -- Initialize the element reference
Element(T & element) : _element(element){}
// Assignment operator -- SET
Element & operator=(const T & that){
_element = that;
return *this;
}
// Element to element assignment -- GET that, SET this
Element & operator=(const Element & that){
this->_element = that._element;
return *this;
}
// Implicit conversion operator -- GET
operator T(){
return _element;
}
private :
T & _element; // Element reference
};
// Return an element class containing a reference to the element
Element operator()(int index){
return Element(_data[index]);;
}
private:
T _data[10];
};
返された Element クラスを T 型であるかのように使用できるようにするには、暗黙的な変換に依存しています。テストしたところ、基本型の基本的な割り当てと算術演算では問題なく動作するようですが、インクリメントやバイナリ シフトなどの演算子では、暗黙的な変換は行われず、操作によってコンパイラ エラーが発生します。そして、Tをクラス構造、ポインターなどとして使用しようとすると、さらに多くの問題が見つかると思います。
それは、クラスの修正機能のために暗黙的な変換に依存することは非常に悪い習慣のように思えるという事実とともに、別のアプローチを考え出す必要があると私に思わせます。現在のアプローチを修正する方法はありますか? 私が取るかもしれない他のアプローチ?または、これをあきらめて、必要な場合にのみ割り当てられる get および set メソッドで常に割り当てられるように operator(row, col) を作成する必要がありますか?