在 C++11 中实现 boost::optional

     2023-02-24     212

关键词:

【中文标题】在 C++11 中实现 boost::optional【英文标题】:Implementing boost::optional in c++11 【发布时间】:2012-08-06 04:25:37 【问题描述】:

我正在尝试使用 c++11 特性实现类似数据结构的 boost::optional。这是我到目前为止所拥有的:

template<typename T>
struct maybe 
  bool valid;

  union 
    T value;
  ;

  maybe() : valid(false) 
  maybe(const T& _v) 
  valid = true;
    new (&value) T(_v);
  
  maybe(const maybe& other) 
    if (other.valid) 
      valid = true;
      new (&value) T(other.value);
    
    else valid = false;
  

  ~maybe() 
     if (valid)
       value.~T();
  

  bool is_valid()  return valid; 

  operator T&() 
    if (valid) return value;
    throw std::bad_exception();
  
;

我利用不受限制的联合功能为可以就地存储的可选值创建正确对齐的空间,而不是动态分配空间。事情大部分都有效,除非我想创建一个带有引用的可能。例如maybe&lt;int&amp;&gt; 导致 g++ 4.7 抱怨:

error: ‘maybe<int&>::<anonymous union>::value’ may not have reference type ‘int&’
because it is a member of a union

我应该怎么做才能使可能的类存储引用?也欢迎对课程提出任何其他改进/建议。

【问题讨论】:

【参考方案1】:

要使用引用进行这项工作,您肯定需要明确的特化,因为您不能对引用进行放置新:您需要使用指针进行存储。

除此之外,代码缺少复制赋值运算符。移动构造函数和移动赋值运算符也很好(特别是因为这是重新实现 boost::optional 的第一大原因:boost 中缺少它们)。

【讨论】:

“这使得你的类不能使用非默认的可构造类型”但这不是真的。该标准似乎表明工会成员禁止自动初始化和销毁​​。 顺便说一句,alignas(T) char data[sizeof(T)] 似乎比你所拥有的更 C++11-ish。 @keveman 这可能是aligned_storage 的实现方式。我发现aligned_storage 对其业务的了解更加明确。 @rmartinho 对于每个人,他自己的。委员会煞费苦心地将aligned_storage 习语移到了语言本身,所以我不想在语言特性上使用库包装器。 @keveman 关于默认可构造性,这很有趣。能否请您参考相应的标准部分?【参考方案2】:

可选类型是为 C++14 提出的,但由于标准中未定义行为的一些极端情况,它被推迟到 C++17。

幸运的是,UB 问题对大多数人来说应该无关紧要,因为所有主要编译器都正确定义了它。因此,除非您使用旧的编译器,否则您实际上可以在项目中放入可用于实现可选类型的代码(它只是一个头文件):

https://raw.githubusercontent.com/akrzemi1/Optional/master/optional.hpp

那么你可以这样使用它:

#if (defined __cplusplus) && (__cplusplus >= 201700L)
#include <optional>
#else
#include "optional.hpp"
#endif

#include <iostream>

#if (defined __cplusplus) && (__cplusplus >= 201700L)
using std::optional;
#else
using std::experimental::optional;
#endif

int main()

    optional<int> o1,      // empty
                  o2 = 1,  // init from rvalue
                  o3 = o2; // copy-constructor

    if (!o1) 
        cout << "o1 has no value";
     

    std::cout << *o2 << ' ' << *o3 << ' ' << *o4 << '\n';

【讨论】:

在 C++11 中实现 boost::barrier

】在C++11中实现boost::barrier【英文标题】:Implementingboost::barrierinC++11【发布时间】:2014-08-1908:57:06【问题描述】:我一直在尝试让项目摆脱所有boost引用并切换到纯C++11。在某一时刻,线程工作者被创建,等待屏障发出“go”命令... 查看详情

如何在 C++11 中实现 make_unique 函数? [复制]

】如何在C++11中实现make_unique函数?[复制]【英文标题】:Howtoimplementmake_uniquefunctioninC++11?[duplicate]【发布时间】:2013-07-2723:11:13【问题描述】:我的编译器不支持make_unique。一个怎么写?template<classT,class...Args>unique_ptr<T>mak... 查看详情

在没有互斥体的 C++11 中实现共享整数计数器的最简单方法:

】在没有互斥体的C++11中实现共享整数计数器的最简单方法:【英文标题】:EasiestwaytoimplementsharedintegercounterinC++11withoutmutexes:【发布时间】:2014-03-1702:30:48【问题描述】:假设我们有以下代码来计算某事发生的次数:inti=0;voidf()//... 查看详情

在 C 中实现 HashMap [关闭]

】在C中实现HashMap[关闭]【英文标题】:ImplementingaHashMapinC[closed]【发布时间】:2010-10-2417:11:08【问题描述】:如何像C++STL中那样从头开始在C中创建Hashmap?将考虑哪些参数以及如何测试哈希图?例如,在您可以说您的哈希图已完... 查看详情

如何在 C 中实现回调函数?

】如何在C中实现回调函数?【英文标题】:HowdoIimplementcallbackfunctionsinC?【发布时间】:2010-05-0814:59:11【问题描述】:gcc4.4.3c89我正在创建一个客户端服务器应用程序,我需要实现一些回调函数。但是,我在回调方面没有太多经验... 查看详情

如何在 C 中实现链表?

】如何在C中实现链表?【英文标题】:HowtoimplementalinkedlistinC?【发布时间】:2010-11-0205:09:47【问题描述】:我正在创建一个linkedlist,就像我问的上一个问题一样。我发现开发链表的最佳方法是将头部和尾部置于另一种结构中。... 查看详情

如何在 C#/Silverlight 中实现带通滤波器

】如何在C#/Silverlight中实现带通滤波器【英文标题】:Howtoimplementaband-passfilterinc#/Silverlight【发布时间】:2009-11-0314:37:56【问题描述】:如何在C#中实现带通滤波器?我在Silverlight中使用自定义MediaStreamSource并使用加法合成来产生声... 查看详情

仅使用一个矩阵在 C 中实现具有部分旋转的 LU 分解

】仅使用一个矩阵在C中实现具有部分旋转的LU分解【英文标题】:ImplementingLUfactorizationwithpartialpivotinginCusingonlyonematrix【发布时间】:2021-11-3011:14:51【问题描述】:为了计算PA=LU分解,我设计了以下C函数,仅使用一个矩阵来存储... 查看详情

如何在 iOS 11 中实现音量快门?

】如何在iOS11中实现音量快门?【英文标题】:HowdoIimplementavolumeshutteriniOS11?【发布时间】:2017-01-1216:16:25【问题描述】:我想在我的相机应用中实现音量快门。当用户按下音量按钮时,我应该得到一个拍照的事件。我正在寻找满... 查看详情

在 Java 中实现“系统”命令

】在Java中实现“系统”命令【英文标题】:Implementingthe"system"commandinJava【发布时间】:2010-11-2502:04:54【问题描述】:我需要一个“系统”函数调用,与Python、Perl、PHP、Ruby和c中的函数调用相同。当它运行在RhinoJavaScript引... 查看详情

如何在 android 中实现 Exoplayer 2.11.1?

】如何在android中实现Exoplayer2.11.1?【英文标题】:HowtoimplementExoplayer2.11.1inandroid?【发布时间】:2020-04-1319:34:55【问题描述】:我正在尝试实现exoplayer这是我的exoplayer版本implementation\'com.google.android.exoplayer:exoplayer:2.11.1\'我正在创... 查看详情

如何在javascript中实现区域/代码折叠

】如何在javascript中实现区域/代码折叠【英文标题】:howtoimplementregions/codecollapseinjavascript【发布时间】:2010-12-2715:45:11【问题描述】:如何在VisualStudio中为JavaScript实现区域(也称为代码折叠)?如果javascript中有数百行,那么在v... 查看详情

使用 @ngtools/webpack 在 Angular 11 + Webpack 4 中实现 AOT

】使用@ngtools/webpack在Angular11+Webpack4中实现AOT【英文标题】:ImplementingAOTinangular11+Webpack4using@ngtools/webpack【发布时间】:2021-04-0215:51:20【问题描述】:我正在尝试在不支持cli的angular项目中实现AOT。我搜索了一下,发现@ngtools/webpack... 查看详情

如何在 Android 11 中实现 New Storage API?

】如何在Android11中实现NewStorageAPI?【英文标题】:HowtoimplementNewStorageAPIinAndroid11?【发布时间】:2021-08-1104:41:42【问题描述】:场景我有两个应用程序,一个是TrackerApp,它记录来电和去电并压缩这些文件,并将文件路径通过Inter-P... 查看详情

在 C++ 中实现 C 库函数

】在C++中实现C库函数【英文标题】:ImplementingClibraryfunctioninC++【发布时间】:2011-10-1416:56:15【问题描述】:在C++中实现C库有什么缺点?该库将用于使用VisualStudio2008或更新版本为普通PC构建Windows应用程序。目前尚不清楚为什么规... 查看详情

在C程序中实现楼梯[重复]

】在C程序中实现楼梯[重复]【英文标题】:ImplementingastaircasewithinaCprogram[duplicate]【发布时间】:2021-12-1805:59:19【问题描述】:我刚开始使用C编程,在实现一个提供“高度”数量的楼梯的程序时遇到了一些困难。#include<cs50.h>#... 查看详情

当我尝试增加矩阵大小时,在 AMD openCL/C 中实现矩阵向量乘法会导致系统死机

】当我尝试增加矩阵大小时,在AMDopenCL/C中实现矩阵向量乘法会导致系统死机【英文标题】:Implementingmatrix-vectormultiplicationinAMDopenCL/CproducessystemfreezeswhenItrytoincreasematrixsize【发布时间】:2012-11-1314:51:43【问题描述】:对于大学的... 查看详情

在 C 中实现动态类型

】在C中实现动态类型【英文标题】:ImplementingdynamictypinginC[duplicate]【发布时间】:2012-04-1623:13:54【问题描述】:可能重复:RepresentingdynamictypinginC在我的计算历史副讲座中,一位教授深入探讨了明显类型化或类型推断语言,并普... 查看详情