首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用boost::optional

如何使用boost::optional
EN

Stack Overflow用户
提问于 2014-03-06 22:47:18
回答 4查看 105K关注 0票数 38

我正在尝试使用boost::optional,如下所示。

代码语言:javascript
复制
#include <iostream>
#include <string>

#include <boost/optional.hpp>

struct myClass
{
   int myInt;
   void setInt(int input) { myInt = input; }
   int  getInt(){return myInt; }
};

boost::optional<myClass> func(const std::string &str)
{
   boost::optional<myClass> value;
   if(str.length() > 5)
   {
      // If greater than 5 length string. Set value to 10
      value.get().setInt(10);
   }
   else if (str.length() < 5)
   {
      // Else set it to 0
      value.get().setInt(0);
   }
   else
   {
      // If it is 5 set the value to 5
      value.get().setInt(5);
   }

   return value;
}


int main()
{
   boost::optional<myClass> v1 = func("3124");
   boost::optional<myClass> v2 = func("helloWorld");
   boost::optional<myClass> v3 = func("hello");

   if (v1)
       std::cout << "v1 is valid" << std::endl;
   else
       std::cout << "v1 is not valid" << std::endl;

   if (v2)
       std::cout << "v2 is valid" << std::endl;
   else
      std::cout << "v3 is not valid" << std::endl;

   if (v3)
      std::cout << "v3 is valid" << std::endl;
   else
      std::cout << "v3 is not valid" << std::endl;

  return 0;
 }

我得到以下错误

prog.exe: /usr/local/boost-1.55.0/include/boost/optional/optional.hpp:631: boost::optional::reference_type boost::optional::get() with T= myClass;boost::optional::reference_type = myClass&:断言``this>is_initialized()‘失败。

可能是可选变量没有正确初始化。怎样做才是正确的呢?

编辑::得到了一些非常好的答案,只是几个问题1.在'func'函数的末尾使用make_optional并返回它是一个好主意吗?另外2.我正在考虑分配boost::none,以强调我没有可以分配的值,这就是boost::none的原因。但不确定这是否有效?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-03-06 22:52:10

默认构造的boost::optional为空-它不包含值,因此不能对其调用get()。你必须用一个有效的值初始化它:

代码语言:javascript
复制
boost::optional<myClass> value = myClass();

或者,您可以使用in-place factory来避免复制初始化(但复制很可能无论如何都会被省略);但是,我没有使用它的经验,所以我不能提供示例。

顺便说一下,您可以使用->代替get(),如下所示:

代码语言:javascript
复制
value->setInt(10);

但这只是一个风格偏好的问题,两者都是同样有效的。

票数 32
EN

Stack Overflow用户

发布于 2014-03-06 23:03:19

怎么做才是正确的呢?

代码语言:javascript
复制
boost::optional<myClass> func(const std::string &str)
{
    if(str.length() > 5)
        return myClass{10};
    if(str.length() < 5)
        return myClass{0};
    return myClass{5};
}

注意,这段代码不需要boost::optional,因为没有返回空对象的代码分支(它在语义上等同于返回myClass实例)。

要返回空的可选参数,请使用以下命令:

代码语言:javascript
复制
boost::optional<myClass> func(const std::string &str)
{
    if(str.length() > 5)
        return myClass{10};
    if(str.length() < 5)
        return myClass{0};
    return boost::none; // return empty object
}

惯用的客户端代码(不要预初始化值):

代码语言:javascript
复制
int main()
{
    if (auto v1 = func("3214"))
        // use *v1 to access value
        std::cout << "v1 is valid" << std::endl;
    else
        std::cout << "v1 is not valid" << std::endl;

    return 0;
}
票数 10
EN

Stack Overflow用户

发布于 2014-03-06 22:57:33

两种简单的方法:

代码语言:javascript
复制
boost::optional<myClass> func(const std::string &str)
{
  boost::optional<myClass> value;
  if(str.length() > 5) // If greater than 5 length string. Set value to 10
    value = 10;
  else if (str.length() < 5) // Else set it to 0
    value = 0;
  else // If it is 5 set the value to 5
    value = 5;

  return value;
}

boost::optional<myClass> func(const std::string &str)
{
  if(str.length() > 5) // If greater than 5 length string. Set value to 10
    return 10;
  else if (str.length() < 5) // Else set it to 0
    return 0;
  else // If it is 5 set the value to 5
    return 5;
}

请注意,从从不返回空可选项的函数返回optional不是一个好主意。

optional的行为类似于读访问上的指针--只有当您已经验证有需要读取的内容时,才能从它中读取值。您可以通过执行bool something_to_read = opt;来检查是否有要读取的内容。

但是,您可以随时对其进行写入。如果那里什么都没有,它就会创造一些东西。如果有什么东西在那里,它会覆盖它。

.get()是一个读操作,而不是一个写操作。(它“读取”引用)只有当optional正在使用并且有数据时,才能安全地使用它。令人困惑的是,您可以写入“读访问”.get()返回值,因为它是一个非常数引用。

所以“读”和“写”可能是不好用的词。:)

有时,将optional看作是值和指针混合在一起会很有帮助。可能存在指向拥有的内存缓冲区的空指针,该缓冲区可能保存或不保存该类型的副本。

如果optional中的指针为null,则缓冲区未初始化。如果它指向缓冲区,则初始化缓冲区。

.get()取消引用该指针并返回结果引用而不进行检查。=检查指针,如果它是null,它执行从rhs到缓冲区的复制构造,并设置指针。如果不是,它只是分配给缓冲区。

(指针是概念性的:通常作为bool标志实现)。

我发现使用*optional比使用optional.get()更好,因为“在取消引用之前必须检查”这一点在使用取消引用操作符时更加明显。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22227839

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档