У меня есть класс с конструктором значений constexpr, но нет копирования или перемещения ctor
class C {
public:
constexpr C(int) { }
C(const C&) = delete;
C& operator=(const C&) = delete;
};
int main() {
constexpr C arr[] = {1, 2};
}
Я обнаружил, что этот код не работает, потому что на самом деле он пытается использовать конструктор перемещения для C, а не конструктор значений для построения на месте. Одна проблема заключается в том, что я хочу, чтобы этот объект был неподвижным (для целей тестирования), но я подумал: «Хорошо, хорошо, я добавлю конструктор перемещения».
class C {
public:
constexpr C(int) { }
C(const C&) = delete;
C& operator=(const C&) = delete;
C& operator=(C&&) = delete;
C(C&&) { /*something*/ } // added, assume this must be non trivial
};
Хорошо, хорошо, теперь он использует конструктор перемещения, и все работает под gcc, но когда я использую clang, он жалуется, потому что конструктор перемещения не помечен constexpr
error: constexpr variable 'arr' must be initialized by a constant expression
constexpr C arr[] = {1, 2};
Если я отмечу конструктор перемещения constexpr, он будет работать под gcc и clang, но проблема в том, что я хочу иметь код в конструкторе перемещения, если он вообще запускается, а конструкторы constexpr должны иметь пустые тела. (Причина, по которой у меня есть код в движении, не стоит вдаваться в подробности).
Так кто здесь прав? Я склоняюсь к тому, что clang будет правильным для отклонения кода.
ПРИМЕЧАНИЕ
Он компилируется со списками инициализаторов и не копируемыми неподвижными объектами, как показано ниже:
class C {
public:
constexpr C(int) { }
C(const C&) = delete;
C& operator=(const C&) = delete;
C& operator=(C&&) = delete;
C(C&&) = delete;
};
int main() {
constexpr C arr[] = {{1}, {2}};
}
Меня больше всего беспокоит, какой компилятор выше правильный.
-fno-elide-constructors, поэтому я предполагаю, что он также должен дать сбой с включенным копированием, как это делает Clang. Используя{{1},{2}}, вы копируете-список-инициализируете объекты, которые не вызывают какой-либо копирующий-ctor, вызываяconstexprctor напрямую, поэтому ошибки не ожидается, и оба компилятора верны - person Piotr Skotnicki   schedule 04.12.2014