重新解释模板参数常量的 C++ 编译器行为

C++ Compiler behavior with re-interpreting template parameter constants

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

像这样的例子:

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 在这种情况下会 always return 2 (铸造后)?还是应该 return 5(铸造后)?

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

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

If a non-static member function of a class X is called for an object that is not of type X, or of a type derived from X, the behavior is undefined.