Мы столкнулись с неожиданной ошибкой компиляции: при превращении класса в шаблон класса произошла ошибка компиляции в его функции-члене. Ошибка жаловалась на то, что локальная переменная constexpr
незатронутого типа не была инициализирована константным выражением.
(ошибка с отредактированными типами, опубликованная здесь для возможности поиска ошибки)
constexpr variable 'localVar' must be initialized by a constant expression
constexpr Derived localVar{...};
note: constructor inherited from base class 'Base' cannot be used in a constant expression; derived class cannot be implicitly initialized
Эта ошибка возникла не в нашей среде Windows, а в Apple Clang. Его можно свести к минимальному примеру , также найденному на Годболте :
struct Base
{
constexpr Base(int, double)
{}
};
struct Derived : public Base
{
// Inherit parent ctor(s)
using Base::Base;
};
// Commenting out the following line clang also compiles
template <class>
struct X
{
void memFun()
{
// The following line is fine.
const Derived derived{0, 3.0};
// This line is fine too
constexpr Base base{0, 2.0};
// The following line produces an error.
constexpr Derived c_derived{0, 3.0};
}
};
Поскольку превращение X
в класс без шаблонов исправляет все, ситуация вызывает беспокойство.
- Законен ли этот код? (то есть какой компилятор находится здесь?)
- Есть ли причины не писать такой код? Или обходные пути, чтобы это работало на всех основных платформах?
Существует также ветка ошибки для G CC, относящаяся к очень похожей (идентичной?) Проблеме .