GCC 8.2.1 и MSVC 19.20 компилируют приведенный ниже код, но Clang 8.0.0 и ICC 19.0.1 этого не делают.
// Base class.
struct Base {};
// Data class.
struct Data { int foo; };
// Derived class.
struct Derived : Base, Data { int bar; };
// Main function.
int main()
{
constexpr int Data::* data_p{ &Data::foo };
constexpr int Derived::* derived_p{ data_p };
constexpr int Base::* base_p{ static_cast<int Base::*>(derived_p) };
return (base_p == nullptr);
}
Сообщение об ошибке с Clang 8.0.0 выглядит следующим образом:
case.cpp:16:33: error: constexpr variable 'base_p' must be initialized by a constant expression
constexpr int Base::* base_p{ static_cast<int Base::*>(derived_p) };
~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Я заметил, что он отлично компилируется с Clang в двух случаях:
- удалить constexpr из последнего определения
- замените строку
constexpr int Derived::* derived_p{ data_p };
наconstexpr int Derived::* derived_p{ &Derived::bar };
.
Следует ли компилировать выражение constexpr (которое приводит к сбою Clang и ICC)?