我正在尝试编写一种结构,以将基数和派生类之间的指针偏移量计算为C++ 03中的常量表达式。代码如下:
template <typename Base, typename Derived, typename Via = Derived>
struct OffsetToBase
{
static const std::ptrdiff_t val =
(const char*const)static_cast<Base*const>(static_cast<Via*const>((Derived*const)(1u << 7))) -
(const char*const)(1u << 7);
};
该代码在GCC中编译,但在clang和VC中不编译。 clang和VC产生的错误基本上表明初始化器不是常量表达式,而clang进一步强调了子表达式
(Derived*const)(1u << 7)
。那么,我的问题是标准对此有何表述?如果初始化程序不符合标准的常量表达式,那么其背后的原因是什么?
更新:
为了您的兴趣,我发现了以下两个讨论:
"Initializer element is not constant" error for no reason in Linux GCC, compiling C
About cast in integer constant expression (in standard C)
但是我不认为相同的规则适用于C++。
最佳答案
根据我对标准的阅读,这不是一个常数表达式:
您的表达式从另一个中减去一个const char指针。这似乎使整个事情失去了被视为常量表达式的资格。
在您的情况下,问题中的两个指针本身都是常量值,即伪值。如果真是这样,那么从理论上就有可能算出它们的减法结果,作为一个常数表达式,但事实并非如此。任何。
我认为您甚至不需要使用指针减法,或者指针的静态强制转换在这里可以工作,您需要对引用进行静态强制转换。以下对我有用,至少在gcc中适用:
class B { int a; };
class C { int b; };
class A : public B, public C {};
int main()
{
static const long n=(long)&static_cast<C &>(*(A *)0);
return 0;
}
关于c++ - 为什么将整数文字类型转换为指针值会导致非const表达式?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27646436/