Я пытался создать класс с членом, который является std :: array типа не для копирования, который мне нужно инициализировать в конструкторе. Я думал, обращаясь к ответам на этот вопрос , что будет работать следующее:
#include <array>
#include <utility>
class Foo {
public:
Foo() {}
Foo(const Foo& rhs) = delete;
Foo(Foo&& rhs) = delete;
};
template<size_t BufferSize>
class FooBuffer {
public:
template<size_t... Is>
FooBuffer(std::index_sequence<Is...>)
: _buffer({{(static_cast<void>(Is), Foo{})...}})
{
}
FooBuffer() : FooBuffer(std::make_index_sequence<BufferSize>{}) {}
private:
std::array<Foo,BufferSize> _buffer;
};
using namespace std;
int main(int, char **) {
FooBuffer<10> foo;
}
И так, начиная с GCC версии 7.1.0 и далее на C ++Флаги 17 или C ++ 17 (GNU) в соответствии с Wandbox:
ссылка на рабочую компиляцию в GCC 7.1.0
Однако, хотя гарантированная поддержка elision копиив списке для Clang ++ начиная с версии 4 и выше, я не могу найти версию, которая принимает вышеуказанный код, вплоть до версии 9.0 или текущей HEAD:
ссылка на ошибку компилятора в Clang
Получаемая ошибка относится к невозможности копирования массива _buffer
:
prog.cc:18:5: error: call to implicitly-deleted copy constructor of 'std::array<Foo, 10UL>'
: _buffer({{(static_cast<void>(Is), Foo{})...}})
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:22:16: note: in instantiation of function template specialization 'FooBuffer<10>::FooBuffer<0, 1, 2, 3, 4, 5, 6, 7, 8, 9>' requested here
FooBuffer() : FooBuffer(std::make_index_sequence<BufferSize>{}) {}
^
prog.cc:32:16: note: in instantiation of member function 'FooBuffer<10>::FooBuffer' requested here
FooBuffer<10> foo;
^
/opt/wandbox/clang-head/include/c++/v1/array:143:9: note: copy constructor of 'array<Foo, 10>' is implicitly deleted because field '__elems_' has a deleted copy constructor
_Tp __elems_[_Size];
^
prog.cc:8:2: note: 'Foo' has been explicitly marked deleted here
Foo(const Foo& rhs) = delete;
^
1 error generated.
Является ли это несогласием в реализации гарантированного исключения копирования между компиляторами? Или я видел здесь признаки на SO, что на гарантированное разрешение копирования нельзя положиться, и он не является обязательным для компилятора. Применимо ли это здесь или только в тех случаях, когда имеется конструктор копирования и GCE не требуется для правильного кода?