ファンキーなオーディオコードを作成し、演算子のオーバーロードを使用して非常にクリーンでシンプルなAPIを作成しようとしています。それはちょっとしたC++の頭の体操になりました...
私が望んでいることは、「インデックスに割り当てられた」種類の複合演算子によってすぐに解決されますが、これは存在しないと確信しています。次のことが可能かどうかについて誰かが何か洞察を持っているでしょうか?
2つのオブジェクトタイプがあります。
Frames frames; // audio data, contains 1 buffer (float *) for each channel
Sample s; // a single sample, 1 float for each channel
つまりSample
、フレームの直交スライスのようなものです。つまり、フレームはの配列ではありませんSample
。オーディオを知っている場合Frames
は、「非インターリーブ」であり、Sample
です。
聖杯...
s = frames[1]; // statement 1. gets a copy of values in frame 1
frames[1] = s; // statement 2. replace values in frame 1 with those in Sample s
最初のものは問題ありません:
// in class Frames...
Sample& operator[](size_t idx) const {
Sample s;
s.left = _leftCh[idx];
s.right = _rightCh[idx];
return s;
}
ただし、上記の関数は参照ではなくデータのコピーを作成するため、2番目の割り当てには注意が必要です。
参照を使用してサンプルを定義してみました...
class Sample {
public:
float& L;
float& R;
Sample(float& lt, float& rt) : L(lt), R(rt) {};
}
しかし、あなたはそれほど単純なことをすることはできません...
Sample s(0.0, 0.0);
s.left = 0.2;
もう1つの考えられる解決策は、2つのステートメントで2つの異なる演算子のオーバーロードを呼び出すことです。次に、ステートメント2がこの[]オーバーロードを呼び出すように強制します。これにより、オブジェクトではなく値を指す新しいFramesオブジェクトが返されSample
ます。
Frames& operator[](size_t idx) {
// Construct an new Frames object whose which
// points to value idx in each channel
Frames f(_size - idx);
f._leftCh = &_leftCh[idx];
f._rightCh = &_rightCh[idx];
return f;
}
Frames
次に、最初の値を置き換えるだけの代入演算子を追加します...
Frames& operator=(const Sample& s) {
_leftCh[0] = s.left;
_rightCh[0] = s.right;
return *this;
}
コンパイラは、メソッドは戻り型だけでなく異なる必要があることを通知しますが、これはconst
、オーバーロードの1つのメソッド名の後に付けることで解決されoperator[]
ます。ここに手がかりがあるのでしょうか?Sample& operator[]...
ステートメント1の呼び出しとステートメント2の呼び出しを行う方法はありますかFrames& operator[]...
。それとも、これを達成するためのはるかに良い方法がありますか?
あなたがこれまでにそれを成し遂げたならば、あなたの忍耐に感謝します!とても有難い...