【问题标题】:casting template value parameter铸造模板值参数
【发布时间】: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&lt;true&gt;Matrix&lt;false&gt;)具有相同的成员,我应该安全吗?

编辑 2 注意这个类没有虚拟方法会有所帮助吗?所以看起来数据成员的逐位副本应该是有效的,无论转置状态如何,所以 c 样式转换(或重新解释转换)应该总是符合我的预期,对吧?

【问题讨论】:

  • 如果你想在运行时改变“类型”,我认为模板参数没有任何用处。
  • 它允许我对矩阵算术进行编译时维度检查,这实际上非常有用。我可以在编译时知道矩阵乘法结果的维度,这允许我将结果分配到堆栈而不是堆上——这对我的应用程序来说是一个巨大的胜利。我可以使用上面示例中的 reinterpret cast 来完成它,我只是想知道这是否是未定义的行为。
  • 这取决于类包含的内容,但如果您可以按值返回一个实例,那就更好了。我真的无法想象Matrix&lt;false&gt; obj; Matrix&lt;true&gt;&amp; 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;这对于按值返回是不可能的。

标签: c++ templates casting


【解决方案1】:

下面的“transpose()”方法尝试在不执行复制的情况下转置对象,方法是简单地返回对自身的引用,但转置标志反转。

这是不可能的。

对于transposed(布尔值)的任何值,Transposable_matrix&lt;true&gt;Transposable_matrix&lt;false&gt; 是两种不同且不兼容的类型。不能使用 static_cast 将一个转换为另一个。

【讨论】:

  • 就像我说的:“但是,可能不出所料,转换操作在编译时失败。”我想知道是否有一种安全的方法可以通过不安全的演员来做到这一点,因为我知道数据字段和方法是相同的。
猜你喜欢
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-06
  • 2014-04-30
  • 2013-11-01
  • 1970-01-01
相关资源
最近更新 更多