如何在C++中使用 std::可选?
How do I use std::optional in C++?
我正在尝试使用 std::optional,但我的代码引发错误。
我已经指定了#include <experimental/optional>
,编译器选项-std=c++1z
,-lc++experimental
。
如何使用std::experimental::optional
?
以下是代码:
#include <experimental/optional>
#include <iostream>
std::experimental::optional<int> my_div(int x, int y) {
if (y != 0) {
int b = x / y;
return {b};
}
else {
return {};
}
}
int main() {
auto res = my_div(6, 2);
if (res) {
int p = res.value();
std::cout << p << std::endl;
}
}
错误信息:
optional.cpp:17:21: error: call to unavailable member function 'value':
int p = res.value();
~~~~^~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/experimental/optional:525:17: note: candidate function has been explicitly made unavailable
value_type& value()
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/experimental/optional:517:33: note: candidate function has been explicitly made unavailable
constexpr value_type const& value() const
^
1 error generated.
操作系统:macOS 10.12.5
编译器版本:
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
好的,在您发布错误后,我可以对此进行调查(但您可以完全这样做)。
总之
这是Apple在OSX上提供的optional
的问题/错误,但是有一个简单的解决方法。
这是怎么回事
文件/Library/Developer/CommandLineTools/usr/include/c++/v1/experimental/optional
将违规函数optional::value
声明为
template <class _Tp>
class optional
: private __optional_storage<_Tp>
{
/* ... */
_LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
constexpr value_type const& value() const
{
if (!this->__engaged_)
throw bad_optional_access();
return this->__val_;
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
value_type& value()
{
if (!this->__engaged_)
throw bad_optional_access();
return this->__val_;
}
/* ... */
};
仅运行预处理器(编译器选项-E
)显示宏扩展到
#define _LIBCPP_INLINE_VISIBILITY
__attribute__ ((__visibility__("hidden"), __always_inline__))
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
__attribute__((unavailable))
特别是,宏_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
在文件中#define
d/Library/Developer/CommandLineTools/usr/include/c++/v1/__config
为
// Define availability macros.
#if defined(_LIBCPP_USE_AVAILABILITY_APPLE)
// ...
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
// ...
#else
// ...
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
// ...
#endif
因此,这是 Apple 对 LLVM 的 libc++ API 的特定更改。顾名思义,原因是苹果没有制造
class bad_optional_access
: public std::logic_error
{
public:
bad_optional_access() : std::logic_error("Bad optional Access") {}
virtual ~bad_optional_access() noexcept;
};
可用,因此无法实现依赖于它的功能(optional::value
)。为什么不提供bad_optional_access
(从而打破标准)尚不清楚,但这可能与必须更改库(dylib)以包含bad_optional_access::~bad_optional_access()
的事实有关。
如何解决
只需改用optional::operator*
int p = *res;
唯一真正的区别是没有进行访问检查。如果你需要,你自己做
template<typename T>
T& get_value(std::experimental::optional<T> &opt)
{
if(!opt.has_value())
throw std::logic_error("bad optional access");
return *opt;
}
template<typename T>
T const& get_value(std::experimental::optional<T>const &opt)
{
if(!opt.has_value())
throw std::logic_error("bad optional access");
return *opt;
}
- 可组合的lambda/std::函数与std::可选
- std::可选实现为联合与字符[]/aligned_storage
- 为什么移动 std::可选不重置状态
- std::可选::value_or()-惰性参数求值
- 用于比较基元类型的std::可选的有趣程序集
- std::可选参数会创建副本吗?
- 在 C++11 上下文中使用 std::可选
- 使用什么 std::可选 or std::unique_ptr
- 为什么null std ::可选的被认为小于任何值,而不是更多
- std::可选的默认构造函数不是 gcc 中的 constexpr?
- 为什么const rvalue合格的std ::可选:: value()返回const rvalue参考
- 如何在C++中使用 std::可选?
- 使用 std::可选标准化,我们可以停止在新代码中使用 nullptr 并弃用它吗?
- clang 5:std ::可选的实例螺钉std :: is_constructiblibstiblesiblinsib
- 使用STD ::可选避免函数中的默认参数有任何优势
- 如何初始化用户定义的数据类型的STD ::可选
- STD ::可选的微不足道默认构造函数
- std::可选和提升::可选是否尊重托管对象的对齐限制?
- 为什么当T不可移动时,STD ::可选的移动构建体不会被删除
- constexpr std ::可选的可能实现