【问题标题】:C++ Compiler behavior with re-interpreting template parameter constants重新解释模板参数常量的 C++ 编译器行为
【发布时间】:2017-03-24 16:11:05
【问题描述】:

在处理 RAII 样式的保护对象时,我最终在模板参数中编码了一些保护状态。这似乎是合理的,例如,如果您想要一个递归/嵌套的保护对象,它知道它有多少层但没有空间开销(我知道是迂腐的)或消除一些运行时开销。不过,这变成了一种学术好奇心......

这样的例子就是一个例子:

template <unsigned depth>
class guard {
    unsigned get_depth() const {return depth;}
};

guard<2> g2;
std::cout << reinterpret_cast< guard<5>* >( &g2 )->get_depth(); // works? crazy? useful?

我一辈子都想不出这样做的正当理由,但它让我思考这是否是合法的 C++,以及编译器应该如何处理这样的事情(如果可以的话)或者它是否是只是彻头彻尾的愚蠢。

我假设因为需要在编译时知道转换目标,所以为转换实例化了相关模板。有没有人发现这样有用的东西,假设它确实有效并且有用途,如果是这样,可以在哪里使用?

我猜的一般问题是 reinterpret_cast 可以更改常量模板参数吗? 如果是这样,这只是一个类型 hack(因为需要一个更好的术语),g2 在这种情况下会 总是返回2(投射后)?还是应该返回5(投射后)?

【问题讨论】:

  • reinterpret_cast 完全符合其名称。你可以用它投射一切。
  • 我知道它的作用,但我以前从未像这样使用过它
  • @πάνταῥεῖ:对于“can”的某些值

标签: c++ c++11 reinterpret-cast


【解决方案1】:

这是未定义的,但不是因为严格的别名规则。对get_depth 的调用既不读取也不修改任何对象的值(模板非类型参数不是对象),因此它不会访问(如[defns.access] 中所定义)严格别名规则含义内的任何内容。

这由[class.mfct.non-static]/2控制:

如果为对象调用类X的非静态成员函数 不是X 类型或从X 派生的类型,行为是 未定义。

【讨论】:

  • @krzaq 对我来说没关系 - 通常我看到人们要么 ping OP 不接受,要么标记要删除的 mod。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多