"Assign to Indexed" C++运算符过载脑筋急转弯
"Assign to Indexed" C++ Operator Overload Brainteaser
我正在编写一些有趣的音频代码,并尝试使用运算符重载来创建一个非常干净和简单的API。它变得有点像C++的脑筋急转弯。。。
我想要的东西会立即通过一种"分配给索引"的复合运算符来解决,我很确定这是不存在的。有人可能对以下是否可能有任何见解吗?
我有两种对象类型。。。。
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;
}
但第二个赋值很棘手,因为上面的函数创建的是数据的副本,而不是引用。
我试着用引用定义Sample。。。
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;
另一个潜在的解决方案是让这两个语句调用两个不同的运算符重载。然后强制执行语句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;
}
编译器通知我,方法的不同之处必须不仅仅是返回类型,但这可以通过在其中一个operator[]
重载的方法名称后面有const
来解决。这里可能有线索吗?有没有办法让语句1调用Sample& operator[]...
,语句2调用Frames& operator[]...
。或者有更好的方法来实现这一点吗??
如果你能走到这一步,谢谢你的耐心!非常感谢。。。
这个怎么样:
class SampleRef {
float &left_, &right_;
public:
SampleRef(float& left, float& right)
: left_(left), right_(right)
{}
operator Sample () {
return Sample(left_, right_);
}
SampleRef& operator= (const Sample &arg) {
left_ = arg.left;
right_ = arg.right;
return *this
}
};
SampleRef Frames::operator[] (size_t idx) {
return SampleRef(_leftCh[idx], _rightCh[idx]);
}
当然,您也可以添加operator[]
的const
过载,它只会返回一个Sample
:
Sample Frames::operator[] (size_t idx) const {
return Sample(_leftCh[idx], _rightCh[idx]);
}
您是否尝试过不重载来计算细节?例如sample = frame.getSample(); frame.setSample(sample);
一旦细节被计算出令您满意,那么您就可以添加语法糖并重载[]
和=
运算符。
看起来您想要维护对原始样本的引用,例如:
sample.right = oldR;
sample.left = oldL;
f[x] = sample;
sample.right = newR;
sample.left = newL;
newSample = f[x];
assert(sample.right == newSample.right && sample.left == newSample.left);
这是正确的吗?如果是这样的话,我认为你不能这样做,因为你把你的样本"拆开"插入到框架中,所以你失去了原来的连接。
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 在的内部插入while循环.把这看作一个脑筋急转弯
- 解决"Theater Row"脑筋急转弯的代码
- "Assign to Indexed" C++运算符过载脑筋急转弯