Избегайте вызова конструктора перемещения

У меня есть следующий пример

#include <cstdint>

class FooC
{
public:
   FooC(uint16_t iPort, uint16_t iPin)
   : PORT(iPort)
   , PIN(iPin)
   {
   };

   ~FooC() = default;

   FooC() = delete;
   FooC(const FooC&) = delete;
   FooC(FooC&&) = delete;

private:
   const uint16_t PORT;
   const uint16_t PIN;
};

int main()
{
    FooC array[2] = {
       FooC(1,2),
       FooC(3,4)
    };
}

и я не хочу вызывать конструктор по умолчанию, перемещать и копировать. В связи с этим я удалил функции. К сожалению, это приводит к следующей ошибке (скомпилировано с С++ 11)

: В функции 'int main()':

: 28: 5: ошибка: использование удаленной функции 'FooC :: FooC (FooC &&)'

 };

 ^

: 16: 4: примечание: заявлено здесь

FooC(FooC&&) = delete;

^~~~

: 28: 5: ошибка: использование удаленной функции 'FooC :: FooC (FooC &&)'

 };

 ^

: 16: 4: примечание: заявлено здесь

FooC(FooC&&) = delete;

^~~~

Компилятор вернул: 1

Можно ли в этом примере вызвать вызов конструктора с параметрами и при этом удалить конструктор по умолчанию, перемещение и копирование?

Ответ 1

В С++ 11 и С++ 14 вы можете использовать вложенные скобки:

FooC array[2] = {{1,2}, {3,4}};

В С++ 17 ваш код уже должен работать так, как написано, благодаря новым правилам prvalue/materialization ("гарантированное исключение копирования").

Ответ 2

Можно ли в этом примере вызвать вызов конструктора с параметрами и при этом удалить конструктор по умолчанию, перемещение и копирование?

Нет с вашим текущим синтаксисом (до С++ 17) и да (в С++ 17).

Pre-С++ 17:

Это невозможно. Инициализация агрегата копирует инициализаторы в агрегат. Это означает, что у вас должен быть доступный конструктор копирования/перемещения. В С++ 11 вы должны передать параметры конструктора в виде их собственного списка braced-init-list. Это означает, что вы не копируете FooC а вместо этого копируете список-инициализирующий FooC в массиве, который вызывает конструктор 2 параметров вместо конструктора копирования/перемещения.

FooC array[2] = {
   {1, 2},
   {3, 4}
};

С++ 17:

У вас больше нет временных объектов в списке braced-init-list, и каждый элемент массива будет инициализироваться напрямую вместо инициализации копии.