暗黙的な変換は、添字演算子オーバーロードを含む、メンバ関数呼び出しの目的のために考慮されていません。
宣言されていないメンバ関数がこのように呼び出されるたびに、コンパイラはオブジェクトを変換できるすべての型を見つけ出す必要があります。コンバーターをコンバーターに変換する)、欠落しているメンバー関数が宣言されているかどうかを確認します。どのようにコードの読者のために混乱することは言うまでもありません(変換は変換演算子のケースでは明白かもしれませんが、変換コンストラクタの場合はそうではありません。
だから私はあなたがパスを渡したいベクトルのメンバ関数のそれぞれのメンバ関数を定義する必要があります
を望むように動作するようにプロップを取得するための記述がより便利な方法があります透過的に透過する。
auto operator[](std::size_t pos) {
return value[pos];
}
auto operator[](std::size_t pos) const {
return value[pos];
}
ラップされたメンバー関数はすべて明示的に宣言する必要があります。別の問題は、型がT
に依存する引数です。たとえば、vector::operator[]
はvector::size_type
を使用しますが、使用する可能性があるすべてのT
には定義されていない可能性があります(確かにfloat
では使用できません)。ここでは妥協を図り、std::size_t
を使用します。
このような「トランスペアレント」ラッパーを作成するための面倒な方法は、継承です。公開されている継承テンプレートは、自動的に親のすべてのメンバー関数を持ち、暗黙的にそれに変換可能であり、親タイプのポインタと参照で参照することができます。しかし、そのようなアプローチの透明性は、主に~vector
が仮想ではないため、少し問題があります。
template<typename T>
struct Prop : private T
{
using T::operator[];
using T::T;
};
注意継承のアプローチはT
としての基本的なタイプを使用してからあなたを防ぐこと:
プライベート継承は、あなたのメンバーのアプローチとしてではなく、非常に良く、構文と同じラッピングすることができます。また、暗黙的な変換も(変換演算子を使用しても)不可能になりますので、の場合、T
を期待するフリー関数でProp
をT
として使用することはできません。
PS。変換演算子は値を返すので、ベクトルをコピーする必要があります。これは望ましくないことがあります。
'p2 [0]'という表現は実際には 'p2.operator [](0)'と同じです(エラーメッセージから推測できるはずです)。また、 'Prop'クラスには' operator [] '関数がありません。 –
問題は、p2 [0]が1つの式とみなされることです。 p2を独自の式と見なすと、std :: vectorへの変換が実行され、.operator [](0)が呼び出されます。私の実際のコードでPropに追加のメンバーがあるので、PropがそのタイプのTの値の透明なコンテナとして、いくつかの属性とともに動作するようにするための表記上の便利な方法があります。 – Roel
そのようなデータをラップする通常の方法は、メンバーアクセス演算子 ' - >'または参照解除演算子 '*'をオーバーロードすることです。それで 'p2-> at(0)'や '(* p2)[0]'のようなことができます。より扱いにくいですが、 'static_cast'よりも優れています。 –