标签: boost-optional

如何防止boost :: optional <T>被错误地构造为0?

boost::optional<T>(1.51)提供了一种构建对我的用户非常危险的对象的方法,我想阻止它.假设我有自己的整数类,我想传递一个可选的这样的整数并将其存储在某个类中:

class myint {
public:
    int m_a;
    myint (int r_a) : m_a(r_a) {
    }
};

struct myclass {
    boost::optional<myint> content;
    myclass (const boost::optional<myint>& arg) : content(arg) {
    }
};
Run Code Online (Sandbox Code Playgroud)

现在,这是用户如何使用该类:

myclass(myint(13));            //correct use
myclass(boost::none);          //correct use
myclass(myint(0));             //correct use
myclass(0);                    //INCORRECT use, this easy typo
                               //equates boost::none which
                               //is not what the user meant
Run Code Online (Sandbox Code Playgroud)

我想了解这里发生了什么,并防止这种行为.


有趣的是,

myclass(1);              //does not compile
Run Code Online (Sandbox Code Playgroud)

boost::none对于我的领域来说,这完全是一个有效的价值,但是boost::none当用户试图输入时,有一个偷偷摸摸的东西0是极其误导和危险的.

意图可能有点隐藏,因为我并没有真正推出一个myint课程而且我真的class myclass没有任何目的.无论如何,我需要向函数发送10个左右的可选ints,并且重复数据删除不起作用.(你可以想象我问你的年龄,身高和财富,还有三个特殊按钮可以检查你是否不想回答问题)


我发布了一个似乎在下面工作的答案(根据Mooing的Duck&Ilonesmiz建议,但更轻).不过,我很高兴听到有关它的评论.

c++ boost boost-optional

8
推荐指数
1
解决办法
1186
查看次数

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

我正在尝试使用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();
  }
};
Run Code Online (Sandbox Code Playgroud)

我利用无限制联合功能为可选值创建一个正确对齐的空间,该空间可以原位存储,而不是动态分配空间.事情主要起作用,除非我想创建一个带引用的<>.例如maybe<int&>导致g ++ 4.7抱怨:

error: …
Run Code Online (Sandbox Code Playgroud)

c++ maybe c++11 boost-optional

7
推荐指数
1
解决办法
4171
查看次数

当我可以返回指针时,为什么要使用boost :: optional

如果我有一个find有时无法找到所需内容的函数,我倾向于使该函数返回一个指针,使得a nullptr指示找不到该东西.

例如

Student* SomeClass::findStudent(/** some criteria. */)
Run Code Online (Sandbox Code Playgroud)

如果Student存在,它将返回指向找到的Student对象的指针,否则它将返回nullptr.

我也看到了boost::optional为这个目的而提倡的.例如,当你想要实现一个可以返回"nothing"的函数时,何时使用boost :: optional以及何时使用std :: unique_ptr?

我的问题是,在这种情况下,没有返回指针是最佳解决方案.即,有可能找不到查询的项目,在这种情况下返回nullptr是一个完美的解决方案.使用类似boost::optional(或任何其他类似解决方案)的东西有什么好处?

请注意,在我的示例中,findStudent只会返回指向由其拥有的对象的指针SomeClass.

c++ c++11 boost-optional

7
推荐指数
2
解决办法
4789
查看次数

基于范围的 for 循环表达式中的临时可选

假设我们有一个返回 的函数std::optional<A>。那么在基于范围的 for 循环中使用结果的正确方法是什么?最简单的方法不起作用:

for (auto&& e : a().value()) {
                   // ^--- A&& is returned, so A is destructed
                   // before loop starts
Run Code Online (Sandbox Code Playgroud)

T optional::value() &&如果我们用代替 ,这个问题就不会存在T&& optional::value() &&,但 STL 和 Boost 都以第二种方式定义它。

处理这种情况的正确方法是什么?我不喜欢我能想到的两种解决方案(沙箱):

std::experimental::optional<A> a() {
  // ...
}

void ok1() {
  // ugly if type of A is huge
  for (auto&& e : A(a().value())) {
     // ...
  }
}

void ok2() {
  // extra variable is not used
  // if for …
Run Code Online (Sandbox Code Playgroud)

c++ std boost-optional c++17

7
推荐指数
1
解决办法
489
查看次数

'_HAS_CXX17' marco 是否可用于自定义项目标头以启用 C++17 语言集功能?

我想创建使用标准 C++ 中的“可选”的头文件。但是,我的标头将从 Visual Studio 2015 和 Visual Studio 2017 项目中引用。

我想要一些东西,例如对于 Visual Studio 2017(带有 C++ 17 lang 功能集),使用 std::optional ,并且在 Visual Studio 2015 中使用 boost::optional 。

我在想这样的事情:

#include <yvals.h>
#if _HAS_CXX17
 #include <optional>
 template <typename T> using Optional = std::optional<T>;
#else
 #include "boost/optional/optional.hpp"
 template <typename T> using Optional = boost::optional<T>;
#endif
Run Code Online (Sandbox Code Playgroud)

这样使用'_HAS_CXX17'宏可以吗?有没有更好的方法来做到这一点?

c++ boost-optional visual-studio-2017 stdoptional

7
推荐指数
1
解决办法
4450
查看次数

boost :: optional不让我重新分配const值类型

在我看来应该有四种变体 boost::optional

  • optional<Foo> =>持有一个可变的Foo,可以在初始化后重新分配

  • optional<Foo const> const =>持有一个const Foo,初始化后无法重新分配

  • optional<Foo> const =>(应该?)保持一个可变的Foo,但在初始化后不能重新分配

  • optional<Foo const> =>(应该?)持有一个const Foo,可以在初始化后重新分配

前2个案例按预期工作.但是对optional<Foo> constconst Foo 的解引用,并且optional<Foo const>在初始化之后不允许重新分配(如本问题所述).

const值类型的重新分配是我遇到的具体内容,错误是:

/usr/include/boost/optional/optional.hpp:486:错误:使 'const的富' 为 '这个' 的参数 '富&富::运算符=(const的富&)' 丢弃限定符[-fpermissive]

它发生在这里:

void assign_value(argument_type val,is_not_reference_tag) { get_impl() = val; }
Run Code Online (Sandbox Code Playgroud)

构造之后,实现使用赋值运算符作为参数化可选的类型.它显然不希望左手操作数是一个const值.但是为什么不能将非const可选项重置为新的const值,例如在这种情况下:

optional<Foo const> theFoo (maybeGetFoo());
while (someCondition) {

    // do some work involving calling some methods on theFoo
    // ...but they should only be const ones

    theFoo = maybeGetFoo();
}
Run Code Online (Sandbox Code Playgroud)

一些问题:

  • 我是否正确,希望这在概念上很好,而且无法做到这只是实施中的侥幸?

  • 如果我不编辑boost源,那么在上面的循环中实现逻辑的干净方法是什么,而不是完全废弃boost :: optional?

  • 如果这确实有意义并且我要编辑boost …

c++ boost const-correctness assignment-operator boost-optional

6
推荐指数
1
解决办法
3856
查看次数

boost :: optional的比较(<),输出(<<)和赋值(=)

我有几个关于如何boost::optional工作的问题.我们先来这样做:

boost::optional<int> i;
Run Code Online (Sandbox Code Playgroud)
  1. 是否i < 3总是等同于*i < 3(和其他关系运算符类似)?
  2. 条件是否正确i < 3并且*i < 3未定义?(i还没有设置任何东西)
  3. 什么std::cout << i打印?
  4. 我很确定这i = 3总是一样的*i = 3.如果是这样,我应该选择哪个?

c++ boost boost-optional

6
推荐指数
1
解决办法
1475
查看次数

在进程间内存中使用boost :: optional是否安全?

请考虑以下结构:

struct ThingThatWillGoInSharedMemory {
    boost::optional<int> opt_value;
};
Run Code Online (Sandbox Code Playgroud)

我正在使用boost :: interprocess来创建共享内存区域.我对boost :: optional的理解是它是一个有区别的联合而不是一个可空的指针.作为反例,使用堆的std :: map和std :: vector之类的东西需要一个显式的分配器来在进程间内存中使用它们,但是boost :: optional,我相当肯定不使用堆并且相当于写作:

struct ThingThatWillGoInSharedMemory {
    bool value_initialised;
    int value;
}
Run Code Online (Sandbox Code Playgroud)

所以它可以开箱即用.如果有人确认这一点,我会很高兴 - 我没有看到在boost :: optional文档中明确提到了进程间案例,只是暗示了.

c++ boost-interprocess boost-optional

6
推荐指数
1
解决办法
997
查看次数

混合boost的multi_array和可选的C++ 11 unique_ptr不起作用

我用G ++ 4.7组建了一个前沿设置(虽然目前我还在使用sudo apt-get boost-all-devDebian Wheezy 附带的boost 1.48 ).

我的代码设置在使用的逻辑数据结构是unique_ptr的多维数组.但是multi_array,如果其中有unique_ptr,似乎也无法构造一个空的单元素数组.这样可行:

boost::multi_array<int, 1> arrWorks (boost::extents[1]);
Run Code Online (Sandbox Code Playgroud)

但这不是:

boost::multi_array< unique_ptr<int>, 1> arrFails (boost::extents[1]);
Run Code Online (Sandbox Code Playgroud)

我想编译器的相关抱怨是:

/usr/include/c++/4.7/bits/stl_uninitialized.h:225:从'void std :: uninitialized_fill_n(_ForwardIterator,_Size,const _Tp&)[with _ForwardIterator = std :: unique_ptr*; _Size = unsigned int; _Tp = std :: unique_ptr]'

optional< unique_ptr<...> >即使我应用了这里提供的补丁,我也遇到了一些问题:

https://svn.boost.org/trac/boost/ticket/1841

(注意:找到通过是否可以移动boost :: optional?)

例如:

boost::optional< unique_ptr<int> > optWorks (new int);

// Fails
boost::optional< unique_ptr<int> > optFails (std::move(optWorks));
Run Code Online (Sandbox Code Playgroud)

我觉得我正在做的事情是合法的.事实上,我已经通过将unique_ptr合并到这个项目中,在所有权转移语义方面发现了一些错误.所以我不想说"哦,这太复杂了,只需使用原始指针".

这是支持推动议程吗?它有时间表吗?我可以在此期间使用任何简单的解决方法吗?

c++ boost-multi-array unique-ptr c++11 boost-optional

5
推荐指数
1
解决办法
745
查看次数

如何解除std :: experimental :: optional?

使用Boost,我可以创建一个可选的就地:

boost::optional<boost::asio::io_service::work> work = boost::in_place(boost::ref(io_service));
Run Code Online (Sandbox Code Playgroud)

并解除它:

work = boost::none;
Run Code Online (Sandbox Code Playgroud)

有了C++ 14 /实验支持,我可以使用以下方法构建一个可选的就地:

std::experimental::optional<boost::asio::io_service::work> work;
work.emplace(boost::asio::io_service::work(io_service));
Run Code Online (Sandbox Code Playgroud)

但我对如何脱离它感到茫然......

c++ optional boost-optional c++14

5
推荐指数
1
解决办法
2393
查看次数