C++11 高效地创建C++;11移动和复制感知结构
我正在尝试组合一个高效的C++1x结构,它可以利用高效的std::move/copy构造/和赋值操作。这些结构分为两个基本类别,POD结构和非POD结构。我已经养成了使用样板代码编写这些结构的习惯,但我非常确信编译器在这方面可以做得比我更好,而且每个类都需要相当多的键入。我的问题是,为了利用默认的编译器操作,我能做的最低限度是什么。例如,我知道一旦定义了一个显式构造函数,就会禁止自动生成move和assignment操作符。此外,我希望没有超类的非POD结构具有默认析构函数,而从基类继承的非POD结构具有默认虚拟析构函数。关于如何有效地执行这些操作的规则对我来说总是有点混乱 页面数据结构的原始版本如下C++11 高效地创建C++;11移动和复制感知结构,c++11,struct,c++14,move,defaulted-functions,C++11,Struct,C++14,Move,Defaulted Functions,我正在尝试组合一个高效的C++1x结构,它可以利用高效的std::move/copy构造/和赋值操作。这些结构分为两个基本类别,POD结构和非POD结构。我已经养成了使用样板代码编写这些结构的习惯,但我非常确信编译器在这方面可以做得比我更好,而且每个类都需要相当多的键入。我的问题是,为了利用默认的编译器操作,我能做的最低限度是什么。例如,我知道一旦定义了一个显式构造函数,就会禁止自动生成move和assignment操作符。此外,我希望没有超类的非POD结构具有默认析构函数,而从基类继承的非PO
using PAGE_DATA = struct page_data {
std::string name;
std::vector<SCRN_TEXT> elements;
std::vector<int> jumpTable;
};
在完成一个测试后,我能够验证锅炉板是否正确
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");
}
intmain(){
std::cout我喜欢我的答案,“…如果你发现自己在写移动运算符和移动构造函数,那是因为你没有充分分解问题。”我喜欢我的答案,“…如果你发现自己在写移动运算符和移动构造函数,那是因为你没有充分分解问题。”您的原始结构已完全可移动构造。您编写的所有额外样板代码已在需要时由编译器生成。您的原始结构已完全可移动构造。您编写的所有额外样板代码已在需要时由编译器生成
我的问题是,为了利用默认的编译器操作,我能做的最低限度是什么
最小值——这是最佳值——是您的原始版本,它充分利用了默认操作
您的page\u data::swap
可能比泛型std::swap
稍有效,并且它不会阻止任何隐式成员函数的生成,因此可能值得保留。但是,如果有可能,它可能只会稍微好一些,因此您可能需要衡量是否值得将类定义弄得乱七八糟n
我的问题是,为了利用默认的编译器操作,我能做的最低限度是什么
最小值——这是最佳值——是您的原始版本,它充分利用了默认操作
您的page\u data::swap
可能比泛型std::swap
稍有效,并且它不会阻止任何隐式成员函数的生成,因此可能值得保留。但是,如果有可能,它可能只会稍微好一些,因此您可能需要衡量是否值得将类定义弄得乱七八糟n、 为什么你坚持在每个结构声明前面粘贴使用所有大写=
?这不是C,你可以typedef struct
东西。@Nicolas,这是C++11的别名(现代的typedef)表示法。大写是别名,小写是结构,这允许我同时使用Typedef和struct,小写的一个用于定义构造函数签名。我知道使用意味着什么。我不知道为什么你认为这样做很重要,甚至是个好主意。就像我说的,这不是C。在C中,strUCT单独创建一个类型名称;在C++中,它是.<代码> StutsAuto是一个完全有效的类型名称。您不需要TyBuff/使用<代码> StutsAuto。为什么在所有结构声明前面都坚持使用AlxBase= ?是C++11的别名(现代类型定义)表示法。大写是别名,小写是结构,这允许我同时使用Typedef和struct,小写的一个用于定义构造函数签名。我知道使用意味着什么。我不知道为什么你认为这样做很重要,甚至是个好主意。就像我说的,这不是C。在C中,strUCT< <代码>不能创建一个类型名;在C++中,它是.<代码> StutsAuto是一个完全有效的类型名称。您不需要TyBuff/使用<代码> StutsAuto。问题是我需要添加一个显式的默认构造函数来避免括号初始化。k({..},{..},{..})这些或使用聚合初始值设定项创建本地PAGE_数据结构。如果我继承了非POD简单结构会发生什么情况。我不确定在可能有struct Foo:public Bar的情况下会发生什么,以及如何确保Foo使用Bar等做了所有正确的事情,@johnco3:“问题是我需要添加一个显式的默认构造函数来避免大括号初始化。"…为什么要?您公开了所有成员;为什么要阻止人们对其使用聚合初始化?仅添加默认构造函数如何比实现复制/移动操作更糟糕?问题是,我需要添加显式默认构造函数以避免大括号初始化。我有t的向量这些页面是数据结构。我必须将页面放回({..},{..},{..},{..})或者使用聚合初始值设定项创建本地PAGE_数据结构。如果我使用非POD简单结构进行继承会发生什么情况。我不确定在可能使用struct Foo:public Bar的情况下会发生什么,以及如何确保Foo使用Bar等做了所有正确的事情,@johnco3:“问题是,我需要添加一个显式的默认构造函数来避免大括号初始化。”…为什么要这样做?你让所有成员都公开了
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;
};
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");
}