Инициализировать член массива класса при удалении конструктора копирования класса

Вот уменьшенная версия варианта использования, над которым я работаю.

#include <mutex>
template<typename T = float>
class Foo
{
public:
    Foo(int x, int y):m_mutex(){}
private:
    std::mutex  m_mutex; // This is must have in my project
};

typedef Foo<float> Foo_typedef;

class Func
{
public:     
    static Foo_typedef static_array[2];
};

Foo_typedef Func::static_array[2] = { Foo_typedef(2,3), Foo_typedef(2,3) };

int main()
{   
    return 0;
}

После компиляции VS 2015 Update 2 выдает следующие ошибки.

error C2280: 'Foo<float>::Foo(const Foo<float> &)': attempting to reference a deleted function
note: see declaration of 'Foo<float>::Foo'

Я оглянулся и подозревал, что это может быть одна из двух причин.

1) Скопируйте элемент конструктора для std::mutex удален

2) То, что я думал, может быть похоже на то, что я вижу.

Который из них? Что я могу сделать, чтобы обойти эту ошибку, генерируемую компилятором 2 обновления VS 2015?

ОБНОВЛЕНИЕ: обновлен конструктор, который принимает некоторые параметры, которые необходимо передать Foo_typedef,

1 ответ

Решение

Вам нужно построить элемент на месте с помощью конструктора:

Foo_typedef Func::static_array[2] = { {2, 3}, {2, 3} };

При этом нет копирования или перемещения, потому что два элемента построены на месте.

Стандарт гласит (§8.5.1/2 [dcl.init.aggr], акцент мой):

Когда агрегат инициализируется списком инициализаторов, [...] элементы списка инициализаторов принимаются в качестве инициализаторов для элементов агрегата [...].

В вашем случае это означает, что Foo_typedef(2,3) будет принят в качестве инициализатора для вашего Foo_typedef и, таким образом, копия будет необходима. В коде, который я дал, {2, 3} будет принят в качестве инициализатора, и будет вызван соответствующий конструктор (без копирования).

Другие вопросы по тегам