Questions tagged «c++11»

C ++ 11是2011年批准的C ++标准的名称。它取代了以前的C ++ 03标准,添加了各种核心语言更改和修补程序以及改进和扩展的标准库。

3
销毁大型列表会溢出我的堆栈吗?
考虑以下单链表实现: struct node { std::unique_ptr<node> next; ComplicatedDestructorClass data; } 现在,假设我停止使用某个std::unique_ptr<node> head超出范围的实例,从而导致其析构函数被调用。 这会否使我的堆栈大到无法容纳足够大的列表?假设编译器会做一个相当复杂的优化(将inline unique_ptr的析构函数插入node,然后使用尾部递归)是否公平,如果我执行以下操作,这会变得更加困难(因为data析构函数会混淆next's',使其变得困难)让编译器注意到潜在的重新排序和尾部调用机会): struct node { std::shared_ptr<node> next; ComplicatedDestructorClass data; } 如果data某种程度上有指向它的指针,node那么尾部递归甚至是不可能的(尽管我们当然应该努力避免这种封装破坏)。 通常,那么应该如何销毁该列表呢?我们无法遍历列表并删除“当前”节点,因为共享指针没有release!唯一的方法是使用自定义删除器,这对我来说真的很臭。

4
C ++标识符中通用字符名称的用途是什么
C ++标准(我在新的标准中注意到了,但是C ++ 03中已经存在)指定通用字符名称,用Unicode代码点/ 表示为\uNNNN和\UNNNNNNNN并表示这些字符。这对于字符串文字很有用,尤其是因为还明确定义了UTF-8,UTF-16和UCS-4字符串文字。但是,标识符中也允许使用通用字符文字。其背后的动机是什么?NNNNNNNNNNNN 语法显然是完全不可读的,链接器的标识符可能经过修饰,而且好像没有任何标准函数可以按名称检索符号一样。那么,为什么有人实际使用带有通用字符文字的标识符呢? 编辑:由于它实际上已经存在于C ++ 03中,因此另一个问题是您是否实际看到了使用它的代码?
11 c++  c++11 

1
在C ++中移动语义-局部变量的移动返回
我的理解是,在C ++ 11中,当您按值从函数返回局部变量时,允许编译器将该变量视为r值引用,并将其“移出”函数以返回它(如果当然不会发生RVO / NRVO)。 我的问题是,这不能破坏现有代码吗? 考虑以下代码: #include <iostream> #include <string> struct bar { bar(const std::string& str) : _str(str) {} bar(const bar&) = delete; bar(bar&& other) : _str(std::move(other._str)) {other._str = "Stolen";} void print() {std::cout << _str << std::endl;} std::string _str; }; struct foo { foo(bar& b) : _b(b) {} ~foo() …
11 c++  c++11 

1
用于微控制器的RTOS的消息队列
我目前正在为微控制器编写RTOS。整个过程都是用C ++ 11编写的-如果有人感兴趣,则指向存储库的链接在底部。 当前,我正在编写一个类,该类是一个简单的数据队列,用于在线程之间(或在中断处理程序和线程之间或中断处理程序和其他中断处理程序之间)传递对象。通常,我尝试遵循在其他项目上找到的一些常见API,但是我没有找到具有emplace()功能并支持超时的并发队列的任何示例。 我一般的“问题”是我无法在这两个接口之间做出决定: (std::chrono::duration<Rep, Period>是模板化类型,为清晰起见,我省略了模板样板) 第一版: template<typename T> class FifoQueue { public: ... template<typename... Args> int tryEmplaceFor(std::chrono::duration<Rep, Period>, Args&&... args); int tryPopFor(T&, std::chrono::duration<Rep, Period>); int tryPushFor(const T&, std::chrono::duration<Rep, Period>); int tryPushFor(T&&, std::chrono::duration<Rep, Period>); ... } 第二版: template<typename T> class FifoQueue { public: ... template<typename... Args> int tryEmplaceFor(std::chrono::duration<Rep, Period>, …

4
什么是表示两个类之间多对多关系的好方法?
假设我有两个对象类型,A和B。它们之间的关系是多对多的,但是它们都不是另一个的所有者。 A和B实例都需要知道连接。这不只是一种方法。 因此,我们可以这样做: class A { ... private: std::vector<B *> Bs; } class B { private: std::vector<A *> As; } 我的问题是:我将函数放在哪里创建和销毁连接? 应该是A :: Attach(B),然后更新A :: Bs和B :: As向量吗? 或者应该是B :: Attach(A),这似乎同样合理。 这些都不对。如果我停止使用代码,并在一周后返回,我确定我将无法回忆起是否应该执行A.Attach(B)或B.Attach(A)。 也许应该是这样的函数: CreateConnection(A, B); 但是创建全局函数似乎也不可取,因为它是专门用于仅使用类A和B的函数。 另一个问题:如果我经常遇到这个问题/要求,我能以某种方式为它解决问题吗?也许可以从共享此类关系的类中派生或使用的TwoWayConnection类? 有什么好的方法可以处理这种情况...我知道如何很好地处理一对多的“ C拥有D”情况,但是这比较棘手。 编辑:只是为了使其更明确,这个问题不涉及所有权问题。A和B都由其他某个对象Z拥有,并且Z负责所有所有权问题。我只对如何创建/删除A和B之间的多对多链接感兴趣。
10 c++  c++11 

3
C ++:使用编译器API而不是C ++功能进行元编程
这最初是一个SO问题,但我意识到这是非常不合常规的,并且根据网站上的实际描述,它可能更适合程序员。因为该问题在概念上具有很大的分量。 我一直在学习clang LibTooling,它是一个非常强大的工具,能够以友好的方式(即以语义的方式,而不是通过猜测)公开代码的整个“坚韧不拔” 。如果clang可以编译您的代码,则clang 可以确定该代码内每个字符的语义。 现在让我退一步。 当人们从事C ++模板元编程时(特别是当冒险超越模板进入聪明的领域,尽管使人恐惧)时,会出现许多实际问题。老实说,对于包括我自己在内的许多程序员而言,模板的许多常规用法也有些令人恐惧。 我想一个很好的例子就是编译时字符串。这是一个已经存在一年多的问题了,但是很显然,到目前为止,C ++对于普通人来说并不容易。尽管看这些选项还不足以引起我的恶心,但我仍然对能够产生神奇的,最高效率的机器代码以适应我的软件中任何花哨的应用程序没有信心。 我的意思是,让我们面对现实吧,伙计们,琴弦非常简单和基本。我们中的某些人只是想要一种便捷的方法来发出带有某些字符串的机器代码,而这些字符串在某些情况下“嵌入”了比直接编写代码时要多得多。在我们的C ++代码中。 输入clang和LibTooling,这将公开源代码的抽象语法树(AST),并允许简单的自定义C ++应用程序正确正确地操作原始源代码(使用Rewriter)以及AST中所有对象的丰富的面向对象的语义模型。它处理很多事情。它了解宏扩展,并让您遵循这些链。是的,我说的是源代码到源代码的转换或翻译。 我在这里的基本论点是,使用clang,现在我们可以创建可执行文件,这些可执行文件本身可以用作C ++软件的理想自定义预处理程序阶段,并且可以使用C ++实现这些元编程阶段。我们仅受以下事实的约束:该阶段必须接受有效的C ++代码的输入,并产生更多有效的C ++代码作为输出。加上您的构建系统适用的任何其他限制。 输入至少必须非常接近有效的C ++代码,因为毕竟clang是编译器的前端,而我们只是在四处寻找并利用其API发挥创意。我不知道是否有任何规定可以定义要使用的新语法,但是显然我们必须开发一种方法来正确解析它并将其添加到clang项目中。期望更多的是在clang项目中超出范围。 没问题 我可以想象一些无操作宏函数可以处理此任务。 查看我正在描述的另一种方法是通过运行我们的源代码的AST(感谢clang及其API)来使用运行时C ++实现元编程构造,而不是使用语言本身可用的更有限的工具来实现它们。这也具有明显的编译性能优势(繁重的模板头与您使用它们的频率成比例地减慢了编译速度。然后,许多已编译的东西被链接器仔细地匹配并丢弃了)。 但是,这样做的代价是在构建过程中引入了额外的一两个步骤,并且还要求(当然)编写一些更详细的软件(但至少是简单的运行时C ++)作为我们工具的一部分。 那不是全部。我非常确定,生成核心语言功能极其困难或不可能的代码可以提供更大的功能空间。在C ++中,您可以编写模板,宏或两者的疯狂组合,但是在clang工具中,您可以在运行时以C ++可以实现的任何方式修改类和函数,同时可以完全访问语义内容,除了模板和宏以及其他所有内容。 因此,我想知道为什么每个人都还没有这样做。是不是来自clang的此功能如此新,并且没人熟悉clang的AST的巨大类层次结构?那不可能。 也许我只是低估了这一点的难度,但是使用clang工具执行“编译时字符串操作”几乎在犯罪上很简单。它很冗长,但是非常简单。所需要的只是一堆无操作宏函数,它们映射到实际的实际std::string操作。clang插件通过获取所有相关的无操作宏调用来实现此目的,并使用字符串执行操作。然后将该工具作为构建过程的一部分插入。在构建过程中,这些无操作宏函数调用会自动评估为其结果,然后作为纯旧的编译时字符串插入到程序中。然后可以照常编译该程序。实际上,结果是该程序的移植性也大大提高,不需要新的支持C ++ 11的编译器。

2
这是C ++中基于“ pImpl”的类层次结构的好方法吗?
我有一个我希望将接口与实现分开的类层次结构。我的解决方案是有两个层次结构:接口的句柄类层次结构和实现的非公共类层次结构。基本句柄类具有一个指向实现的指针,派生的句柄类将其强制转换为派生类型的指针(请参见function getPimpl())。 这是我对带有两个派生类的基类的解决方案的草图。有更好的解决方案吗? 文件“ Base.h”: #include <memory> class Base { protected: class Impl; std::shared_ptr<Impl> pImpl; Base(Impl* pImpl) : pImpl{pImpl} {}; ... }; class Derived_1 final : public Base { protected: class Impl; inline Derived_1* getPimpl() const noexcept { return reinterpret_cast<Impl*>(pImpl.get()); } public: Derived_1(...); void func_1(...) const; ... }; class Derived_2 …
9 design  c++  c++11 

1
C ++序列化设计评论
我正在编写一个C ++应用程序。大多数应用程序都需要读写数据引用,这一点也不例外。我为数据模型和序列化逻辑创建了一个高级设计。这个问题要求考虑以下特定目标对我的设计进行审查: 以一种简单灵活的方式来读取和写入任意格式的数据模型:原始二进制,XML,JSON等。等 数据格式应与数据本身以及请求序列化的代码分离。 为了确保序列化尽可能地没有错误。I / O具有多种固有的风险:我的设计是否引入了更多的失败方法?如果是这样,我如何重构设计以减轻这些风险? 该项目使用C ++。无论您是喜欢还是讨厌它,语言都有其自己的处理方式,并且设计旨在与该语言一起工作,而不是反对它。 最后,该项目基于wxWidgets构建。当我在寻找适用于更一般情况的解决方案时,此特定实现应与该工具箱配合良好。 接下来是用C ++编写的一组非常简单的类,它们说明了设计。这些不是我到目前为止已经部分编写的实际类,此代码仅说明了我正在使用的设计。 首先,一些示例DAO: #include <iostream> #include <map> #include <memory> #include <string> #include <vector> // One widget represents one record in the application. class Widget { public: using id_type = int; private: id_type id; }; // Container for widgets. Much more …
9 design  c++  c++11 

1
密钥/价值商店开发移植到现代C ++
我正在开发类似于Cassandra的数据库服务器。 开发从C语言开始,但是没有类,事情变得非常复杂。 目前,我在C ++ 11中移植了所有内容,但我仍在学习“现代” C ++,并对很多事情有疑问。 数据库将使用键/值对。每对都有更多信息-什么时候创建以及何时过期(如果不过期则为0)。每对都是不可变的。 关键是C字符串,值是空*,但至少目前我也使用C字符串作为值。 有抽象IList类。它从三个类继承 VectorList -C动态数组-类似于std :: vector,但使用 realloc LinkList -用于检查和性能比较 SkipList -最终将使用的类。 将来我可能Red Black也会做树。 每个都IList包含零个或多个指向对的指针,并按键排序。 如果IList太长,可以将其保存在磁盘上的特殊文件中。这个特殊文件是的read only list。 如果您需要搜索密钥, 首先在存储器IList中搜索(SkipList,SkipList或LinkList)。 然后将搜索发送到按日期排序的文件 (最新的文件在前,最早的文件在后)。 所有这些文件都在内存中映射。 如果未找到任何内容,则找不到密钥。 我对事情的执行毫无疑问IList。 目前令人困惑的是: 这些对的大小不同,它们由分配,new()并已std::shared_ptr指向它们。 class Pair{ public: // several methods... private: struct Blob; std::shared_ptr<const Blob> _blob; }; struct Pair::Blob{ uint64_t …
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.