Я пытаюсь собрать эффективную структуру C++ 1x, которая может эффективно использовать операции std :: move/copy construct and and assign. Эти структуры относятся к двум основным категориям: структурам POD и структурам, отличным от POD. Я привык писать эти структуры, используя шаблонный код, но я уверен, что компилятор может сделать лучше, чем я, и его довольно много набирать для каждого класса. Мой вопрос - это то, что я могу сделать, чтобы воспользоваться преимуществами операций компилятора по умолчанию. Я знаю, например, что, как только я определяю один явный конструктор, который подавляет автоматическую генерацию операторов перемещения и присваивания. Также мне хотелось бы, чтобы структуры non POD, у которых нет суперклассов, чтобы иметь деструктор по умолчанию, и те, которые наследуют от базовых классов, имеют дефолтный виртуальный деструктор. Правила о том, как делать эти операции эффективно, всегда были немного сбиты с толку.Эффективное создание структур C++ 11 для перемещения и копирования
Оригинальная версия PAGE_DATA структуры является следующим
using PAGE_DATA = struct page_data {
std::string name;
std::vector<SCRN_TEXT> elements;
std::vector<int> jumpTable;
};
Затем я добавил шаблонный код, чтобы сделать эту структуру данных двигаться в курсе, и я также добавил явный конструктор (без которого я вынужден инициализировать его агрегат инициализация с использованием фигурных скобок, которые не читаются особенно хорошо).
using PAGE_DATA = struct page_data {
explicit page_data(const std::string& rName = std::string(),
const std::vector<SCRN_TEXT>& rElements = std::vector<SCRN_TEXT>(),
const std::vector<int>& rJumpTable = std::vector<int>())
: name(rName)
, elements(rElements)
, jumpTable(rJumpTable)
{}
//! Defaulted copy constructor.
page_data(const page_data&) = default;
//! Defaulted move constructor.
page_data(page_data&&) = default;
//! Non-throwing copy-and-swap idiom unified assignment.
page_data& operator=(page_data rhs) {
rhs.swap(*this);
return *this;
}
//! Non-throwing-swap idiom.
void swap(page_data& rhs) noexcept {
// enable ADL (not necessary in our case, but good practice)
using std::swap;
// swap base members
// ...
// swap members here
swap(name, rhs.name);
swap(elements, rhs.elements);
swap(jumpTable, rhs.jumpTable);
}
virtual ~page_data() = default;
std::string name;
std::vector<SCRN_TEXT> elements;
std::vector<int> jumpTable;
};
зависимых простого POD структур, которые выкрикивали приведены ниже:
using COLOR_TYPE = enum color_type
{
BLACK = 0x0,
CYAN = 0x1,
RED = 0x2,
YELLOW = 0x3,
GREEN = 0x4,
MAGENTA = 0x5,
AMBER = 0x6,
WHITE = 0x7
};
using SIZE_TYPE = enum size_type {
SMALL_CHAR = 0x0,
BIG_CHAR = 0x1
};
using MODIFY_TYPE = enum modify_type {
NORMAL = 0x0,
UNDER = 0x2,
FLASH = 0x4,
FLASH_UNDER = 0x6
};
using SCREEN_ATTR = struct screen_attr {
COLOR_TYPE color : 4;
SIZE_TYPE size : 2;
MODIFY_TYPE blink : 4;
unsigned char unused : 6;
};
using CDU_ROWCOL = struct cdu_rowcol {
int v;
int h;
};
using SCRN_TEXT = struct scrn_text {
CDU_ROWCOL loc;
SCREEN_ATTR attrib;
std::string text;
};
После собирает live coliru demo, я был в состоянии проверить, что котел пластина делает правильную вещь ,.
int main() {
std::cout << "assertions work fine" << std::endl;
static_assert(std::is_copy_constructible<PAGE_DATA>(), "not copy constructible");
static_assert(std::is_move_constructible<PAGE_DATA>(), "not move constructible");
}
Почему вы настаиваете на том, чтобы придерживаться 'using ALL_CAPS =' перед каждой декларацией структуры? Это не C, где вы делаете «typedef struct». –
@NicolBolas Это псевдоним C++ 11 (современный typedef). Шапки - это псевдоним, а нижний регистр - это структура, это позволяет мне использовать как Typedef, так и Struct вместе, нижний регистр используется для определения сигнатуры конструктора. – johnco3
Я знаю, что означает 'использование' * означает *. Я не знаю, почему вы думаете, что это важно или даже хорошая идея. Как я уже сказал, это не C. В C сама 'struct' не создавала бы имя типа; в C++, это так. 'screen_attr' является * полностью допустимым * именем типа. Вам не требуется typedef/использование 'SCREEN_ATTR'. –