【发布时间】:2011-11-14 05:37:32
【问题描述】:
我有一个带有布尔模板参数的模板类。是否有合法的方式将其转换为对同一对象的引用但布尔值反转?
作为一个说明性示例,下面我有一个 Matrix 类,其转置可以由相同的对象数据表示,但“转置”模板参数颠倒了。
template <bool transposed>
class Transposable_matrix
{
...
Transposable_matrix<!transposed>& transpose()
{
static_cast<Transposable_matrix<!transposed>& >(*this);
}
};
上面的“transpose()”方法试图在不执行复制的情况下转置对象,方法是简单地返回对自身的引用,但将转置标志反转。但是,可能不出所料,转换操作在编译时失败。有没有可接受的方法来做到这一点?我猜 reinterpret_cast 不能保证正确性。我可以使用代理对象来表示转置对象,但这将涉及重构整个类。
编辑
使用 reinterpret cast 后,我所有的单元测试都通过了。但是重新解释演员表让我很紧张——这是否属于“未定义行为”的范畴,而我只是走运了?或者由于这两种类型(Matrix<true> 和Matrix<false>)具有相同的成员,我应该安全吗?
编辑 2 注意这个类没有虚拟方法会有所帮助吗?所以看起来数据成员的逐位副本应该是有效的,无论转置状态如何,所以 c 样式转换(或重新解释转换)应该总是符合我的预期,对吧?
【问题讨论】:
-
如果你想在运行时改变“类型”,我认为模板参数没有任何用处。
-
它允许我对矩阵算术进行编译时维度检查,这实际上非常有用。我可以在编译时知道矩阵乘法结果的维度,这允许我将结果分配到堆栈而不是堆上——这对我的应用程序来说是一个巨大的胜利。我可以使用上面示例中的 reinterpret cast 来完成它,我只是想知道这是否是未定义的行为。
-
这取决于类包含的内容,但如果您可以按值返回一个实例,那就更好了。我真的无法想象
Matrix<false> obj; Matrix<true>& ref = a.transpose();的含义是什么 原来的obj仍然存在,但它被转置了,尽管类型另有说明?? -
原始 obj 未修改,ref 是转置形式的 obj 的“视图”,对其进行的所有操作将简单地反转它们的索引顺序。例如,对于所有 i,j,obj(i,j) == ref(j,i) 和 &obj(i,j) == &ref(j,i)。和 ref(i,j) = 1234;断言(obj(j,i)== 1234)。
-
另外,它可以让你对转置版本进行赋值,Matlab 风格: mat_2x3.transpose() = mat_3x2;这对于按值返回是不可能的。