这是value_or()C++ 17标准的定义:
template <class U> constexpr T value_or(U&& v) const&;效果:相当于:
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));备注:如果
is_copy_constructible_v<T> && is_convertible_v<U&&, T>是false,该程序是不正确的.
(右值超载类似)
效果value_or被描述为等同于return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
operator bool是noexcept.operator*是不是 noexcept(即使它没有抛出,可能是因为如果在可选项不包含值时使用UB,它仍然可以失败).但是,我们保证永远不会尝试返回包含的值,除非我们有一个.
所以不能value_or被宣布noexcept给予is_nothrow_copy_constructible<T> && noexcept(static_cast<T>(std::forward<U>(v)))?
我尝试使用不同的编译器(包括gcc 6.1)编译以下程序:
#include <optional>
int main()
{
std::optional<int> o1;
}
Run Code Online (Sandbox Code Playgroud)
输出是
main.cpp:1:20:致命错误:可选:没有这样的文件或目录#include可选
对于此处给出的示例,情况甚至如此:http: //en.cppreference.com/w/cpp/utility/optional/optional
任何线索为什么?
我正在使用 std::optional 编写一些代码,并且想知道 C++17 的“带有初始化程序的 if 语句”是否能够帮助解压缩值?
std::optional<int> optionalInt = GetOptionalInt();
Run Code Online (Sandbox Code Playgroud)
我在这里编写函数 Unpack:
if( auto [value, has_value] = optionalInt.Unpack(); has_value )
{
// Use value here.
}
Run Code Online (Sandbox Code Playgroud)
但是,我的问题是。C ++ 17“带有初始化程序的if语句”在这里有帮助吗?如果是这样,它将如何编码?
更新,这实际上主要是使用 optional 时的一个问题,这非常容易被误用,因为 optional 和 *optional 都返回 bool 并且当有人尝试访问该值并忘记 *.
std::optional::value() 有两个以上的重载
constexpr T& value() &;
constexpr const T & value() const &;
constexpr T&& value() &&;
constexpr const T&& value() const &&;
Run Code Online (Sandbox Code Playgroud)
返回const右值引用有什么意义?
我能想到的唯一原因是使编译器能够帮助捕获未完成的行为(真的很奇怪),如下所示
auto r = std::cref(const_cast<const std::optional<int>&&>(
std::optional<int>{}).value());
Run Code Online (Sandbox Code Playgroud)
如果std::optional::value()已返回a,const T&则上述代码将编译,并在r reference_wrapper以后使用时导致未定义的行为.
以上返回的是否有任何其他角落案例const T&&?
我想创建使用标准 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'宏可以吗?有没有更好的方法来做到这一点?
如何就地构造一个可选的聚合?看来我只能构建一个可选的单一事物,而不能构建一个可选的事物集合。
#include <optional>
#include <iostream>
struct Unmovable
{
Unmovable(const Unmovable&) = delete;
Unmovable(Unmovable&&) = delete;
Unmovable& operator=(const Unmovable&) = delete;
Unmovable& operator=(Unmovable&&) = delete;
explicit Unmovable(const char* msg) {
std::cout << msg << '\n';
}
};
struct Things
{
Unmovable one;
Unmovable two;
};
int main(int argc, char* argv[]) {
const bool y = argc > 1 && argv[1][0] == 'y';
std::optional<Unmovable> optionalThing = y
? std::optional<Unmovable>{"works"}
: std::nullopt;
std::optional<Things> optionalThings = y
? std::optional<Things>{
#if ATTEMPT == 1
"jadda", …Run Code Online (Sandbox Code Playgroud) 在对涉及 的代码进行基准测试时std::optional<double>,我注意到 MSVC 生成的代码的运行速度大约是 clang 或 gcc 生成的代码的一半。在花了一些时间减少代码后,我注意到 MSVC 显然在为std::optional::operator=. 使用std::optional::emplace()不会表现出速度减慢。
以下功能
void test_assign(std::optional<double> & f){
f = std::optional{42.0};
}
Run Code Online (Sandbox Code Playgroud)
产生
sub rsp, 24
vmovsd xmm0, QWORD PTR __real@4045000000000000
mov BYTE PTR $T1[rsp+8], 1
vmovups xmm1, XMMWORD PTR $T1[rsp]
vmovsd xmm1, xmm1, xmm0
vmovups XMMWORD PTR [rcx], xmm1
add rsp, 24
ret 0
Run Code Online (Sandbox Code Playgroud)
注意未对齐的 mov 操作。相反,函数
void test_emplace(std::optional<double> & f){
f.emplace(42.0);
}
Run Code Online (Sandbox Code Playgroud)
编译为
mov rax, 4631107791820423168 ; 4045000000000000H
mov BYTE PTR [rcx+8], 1
mov …Run Code Online (Sandbox Code Playgroud) 使用时经常会出现以下情况std::optional:
void bar(const Foo*);
void baz(const std::optional<Foo>& foo) {
// This is clunky to do every time.
bar(foo.has_value() ? &foo.value() : nullptr);
// Why can't I do this instead?
bar(foo.as_ptr());
}
Run Code Online (Sandbox Code Playgroud)
这种情况使得采用 变得很烦人std::optional,因为这样将它与需要指针的现有代码一起使用是非常不方便的。那么为什么没有.as_ptr()提供类似的东西std::optional呢?这似乎是一个非常明显的便利功能。
我正在编写一个小型 C++11 库,我相信std::optional它会是一些可以返回nullptr. 然而,std::optional这是 C++17 的功能。由于 C++11 是一项要求,因此我正在寻找在std::optional保持兼容性的同时使用的方法。
我发现功能宏可以测试。我想我可以用它来检测是否std::optional可用......但是当它不可用时最好的方法是什么?
我应该提供自己的std::optional实现吗?
不可用nullptr时返回?std::optional(可能会弄乱我的代码。)
还是放弃这个想法,nullptr只继续返回?
我正在简单地阅读参考文献,并进入了讨论使用可选参考文献的部分。赫伯给出避免的原因之一optional<T&>是因为这些情况可以“同样很好地代表optional<not_null<T*>>”
我很困惑你什么时候会想要optional<not_null<T*>>。在我看来,optional取消已经结束了not_null,那么在这种情况下为什么不直接使用原始指针呢?
c++ ×10
stdoptional ×10
c++17 ×5
c++11 ×2
construction ×1
noexcept ×1
notnull ×1
nullptr ×1
option-type ×1
std ×1
visual-c++ ×1
x86-64 ×1