Взгляните на следующий пример кода, в котором используется класс uncopiable
, аналогичный boost::noncopyable
:
#include <vector>
class uncopiable {
using self = uncopiable;
protected:
uncopiable() {}
~uncopiable() {}
uncopiable(const self&) = delete;
self& operator=(const self&) = delete;
};
struct A {
struct B : uncopiable {
using self = B;
B() {
}
B(B&&) = default;
self& operator=(B&&) = default;
~B() {
}
};
A() { v.emplace_back(); }
~A() {}
private:
std::vector<B> v;
};
int main () {}
Поскольку я хотел, чтобы внутренний класс перемещался только, я явно указал его конструктор перемещения и оператор присваивания по умолчанию, но также, поскольку я слышал, что рекомендуется указывать все «специальные функции-члены», в таком случае я унаследовал его от uncopiable
. Проблема в том, что компиляция завершается неудачей с каждым компилятором, и отображается что-то похожее на следующее сообщение об ошибке (это сообщение является выдержкой из сообщения clang):
/usr/include/c++/v1/memory:1645:31: ошибка: вызов неявно удаленного конструктора копирования 'A::B'
...
main.cpp: 26:10: примечание: здесь запрашивается специализация шаблона функции 'std::__1::vector >::emplace_back‹>'
main.cpp: 19: 3: примечание: конструктор копирования неявно удален, поскольку «B» имеет объявленный пользователем конструктор перемещения
Это можно было бы исправить, удалив наследование (операции копирования все равно не создавались бы). Но писать операции копирования, которые после этого явно удаляются внутри класса, тоже нормально.
Мои вопросы: почему это происходит? Можно ли считать недостатком отключение конструкторов/операторов присваивания через наследование вспомогательных классов?
noncopiable
также неявно являетсяnonmovable
, поэтомуB
также является неподвижным.= default
явно запрашивает неявное определение, которое в этом случае удаляется. (По сути, установка специальных функций-членов по умолчанию — это просто способ изменить их объявление, а не их определение.) - person dyp   schedule 11.10.2015default
, все мои варианты использования работали нормально. - person Predelnik   schedule 11.10.2015