jo-*_*art 11 c++ constexpr c++11
我遇到了一个g ++的问题,使用static_cast在constexpr上下文中向上转换成员指针.请参阅代码示例.
在使用g ++版本6.3和7.0进行编译时,它们会出现编译错误,指出reinterpret_cast不是常量表达式.虽然clang 4.0版没有错误,但我认为这是正确的,因为这里没有reinterpret_cast.
这是g ++或clang中的错误吗?什么是正确的行为?
struct Base {};
struct Derived : Base
{
int i;
};
struct Ptr
{
constexpr Ptr(int Derived::* p) : p(static_cast<int Base::*>(p)){}
int Base::* p;
};
constexpr Ptr constexpr_ptr(&Derived::i);
Run Code Online (Sandbox Code Playgroud)
编译器输出
g++ -c -std=c++14 test.cpp
test.cpp:17:40: in constexpr expansion of ‘Ptr(&Derived::i)’
test.cpp:11:41: error: a reinterpret_cast is not a constant expression
constexpr Ptr(int Derived::* p) : p(static_cast<int Base::*>(p)){}
^~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
GCC 大概误解了[expr.static.cast]/12,它允许您进行强制转换并指出
如果类
B包含原始成员,或者是包含原始成员的类的基类或派生类,则生成的指向成员的指针将指向原始成员。否则,行为是未定义的。
由于Base确实是包含该成员的类的基类,因此应该定义行为,并且构造函数调用常量表达式。