我正在阅读文档,std::experimental::optional
我对它的作用有很好的了解,但我不明白何时应该使用它或我应该如何使用它.该网站不包含任何例子,这使我更难理解这个对象的真实概念.何时是std::optional
一个很好的选择,它如何补偿以前的标准(C++ 11)中没有找到的东西.
我如何"重置"/"取消设置" boost::optional
?
optional<int> x;
if( x )
{
// We won't hit this since x is uninitialized
}
x = 3;
if( x )
{
// Now we will hit this since x has been initialized
}
// What should I do here to bring x back to uninitialized state?
if( x )
{
// I don't want to hit this
}
Run Code Online (Sandbox Code Playgroud) 我有类似以下代码:
#include <boost/optional.hpp>
::boost::optional<int> getitem();
int go(int nr)
{
boost::optional<int> a = getitem();
boost::optional<int> b;
if (nr > 0)
b = nr;
if (a != b)
return 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用Boost 1.53使用GCC 4.7.2进行编译时,使用以下命令:
g ++ -c -O2 -Wall -DNDEBUG
发出以下警告:
13:3:警告:' ((void)&b +4)'可以在此函数中未初始化使用[-Wyybe-uninitialized]
显然,根本问题在于海湾合作委员会.请参阅GCC Bugzilla 有没有人知道解决方法?
我想尝试使用boost::optional
如下.
#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 …
Run Code Online (Sandbox Code Playgroud) 我一直试图在一个带有boost::optional
成员变量的类中定义一个默认的移动构造函数.
#include <boost/optional.hpp>
#include <utility>
#include <vector>
struct bar {std::vector<int> vec;};
struct foo {
foo() = default;
foo(foo&&) = default;
boost::optional<bar> hello;
};
int main() {
foo a;
foo b(std::move(a));
}
Run Code Online (Sandbox Code Playgroud)
我的编译器支持移动语义和默认的移动构造函数,但我不能让它工作.
Run Code Online (Sandbox Code Playgroud)% clang++ foo.cc -std=c++11 -stdlib=libc++ foo.cc:15:7: error: call to deleted constructor of 'foo' foo b(std::move(a)); ^ ~~~~~~~~~~~~ foo.cc:9:3: note: function has been explicitly marked deleted here foo(foo&&) = default; ^ 1 error generated.
有没有办法移动a boost::optional
而不修改Boost的源代码?或者我应该等到Boost支持移动?
我过去遇到了同样的问题boost::any
.
Boost.Optional使用虚拟类型来允许构建未初始化的实例boost::optional<T>
.调用此类型none_t
,none
为方便起见,已在头中定义了一个实例,允许我们编写如下代码:
boost::optional<int> uninitialized(boost::none);
Run Code Online (Sandbox Code Playgroud)
看一下定义none_t
,我注意到它实际上是一个typedef,对应于某个伪结构的指向成员的指针:
namespace boost {
namespace detail { struct none_helper{}; }
typedef int detail::none_helper::*none_t ;
none_t const none = (static_cast<none_t>(0)) ;
} // namespace boost
Run Code Online (Sandbox Code Playgroud)
使用这样一个复杂的typedef比这样的简单空结构有什么好处?
namespace boost {
struct none_t {};
none_t const none;
} // namespace boost
Run Code Online (Sandbox Code Playgroud) 根据我的理解,有两种方法可以实现有时不返回结果的函数(例如,在ppl列表中找到的人).
* - 我们忽略原始ptr版本,与bool标志配对,以及未找到版本时的异常.
boost::optional<Person> findPersonInList();
Run Code Online (Sandbox Code Playgroud)
要么
std::unique_ptr<Person> findPersonInList();
Run Code Online (Sandbox Code Playgroud)
那么有什么理由可以优先于另一个吗?
为什么std::optional
(目前std::experimental::optional
在libc ++中)没有引用类型的专门化(与之相比boost::optional
)?
我认为这将是非常有用的选择.
是否有一些对象引用了STL中可能已存在的对象语义?
考虑以下示例,我们解析数据并将结果传递给下一个函数:
Content Parse(const std::string& data);
void Process(Content content);
int main()
{
auto data = ReadData();
Process(Parse(data));
}
Run Code Online (Sandbox Code Playgroud)
现在让我们使用更改代码std::optional
来处理失败的解析步骤:
optional<Content> Parse(const std::string& data);
void Process(Content content);
int main()
{
auto data = ReadData();
auto content = Parse(data);
if (content)
Process(move(*content));
}
Run Code Online (Sandbox Code Playgroud)
移动是否有效optional<T>::value()
?如果它std::optional
可以,它也有效boost::optional
吗?
假设一个方法返回这样的东西
boost::optional<SomeClass> SomeMethod()
{...}
Run Code Online (Sandbox Code Playgroud)
现在假设我有类似的东西
boost::optional<SomeClass> val = SomeMethod();
Run Code Online (Sandbox Code Playgroud)
现在我的问题是如何从val中提取SomeClass?
所以我可以这样做:
SomeClass sc = val ?
Run Code Online (Sandbox Code Playgroud)