标签: stdoptional

在 C++11 上下文中使用 std::Optional

我正在编写一个小型 C++11 库,我相信std::optional它会是一些可以返回nullptr. 然而,std::optional这是 C++17 的功能。由于 C++11 是一项要求,因此我正在寻找在std::optional保持兼容性的同时使用的方法。

我发现功能宏可以测试。我想我可以用它来检测是否std::optional可用......但是当它不可用时最好的方法是什么?

我应该提供自己的std::optional实现吗?

不可用nullptr时返回?std::optional(可能会弄乱我的代码。)

还是放弃这个想法,nullptr只继续返回?

c++ nullptr c++11 c++17 stdoptional

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

std::Optional 与 nullptr 相比有哪些优点/缺点?

我在互联网上看了几部在线 std::Optional 纪录片。但是我无法找到以下两个案例之间的任何直接比较:

情况1:

SomePointer* foo::get_some_pointer(cont int value) {
    
    auto result = myMap.find(value);

    if (result != myMap.end()) {
        return const_cast<SomePointer*>(&result->second);
    }

    return nullptr;
}
Run Code Online (Sandbox Code Playgroud)

案例2

 std::optional<SomePointer*> foo::get_some_pointer (cont int value) {
    
        auto result = myMap.find(value);
    
        if (result != myMap.end()) {
            return std::optional<SomePointer*>{&result->second};
        }
    
        return std::nullopt;
    }
Run Code Online (Sandbox Code Playgroud)

情况 1 相对于情况 2(nullopt 优于 nullptr)有哪些优点/缺点?

c++ stdoptional

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

不对 value_or() 进行惰性求值的用例是什么?

foo.value_or(bar())我在代码中使用时遇到了麻烦,因为我不希望当可选变量有值bar()时调用该函数。foo我发现这个问题解释了value_or()不使用惰性求值。

现在我想知道为什么会这样,惰性求值一直是 C 和 C++ 中条件语句的标准方面。我发现这非常违反直觉,我认为我不是第一个也不会是最后一个被它绊倒的人。由于存在要求了解设计者想法的风险std::optional,是否有一个用例可以解释为什么惰性评估在这里不是一个好主意?

c++ stl lazy-evaluation c++17 stdoptional

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

什么时候使用可选&lt;not_null&lt;T*&gt;&gt;

我正在简单地阅读参考文献,并进入了讨论使用可选参考文献的部分。赫伯给出避免的原因之一optional<T&>是因为这些情况可以“同样很好地代表optional<not_null<T*>>

我很困惑你什么时候会想要optional<not_null<T*>>。在我看来,optional取消已经结束了not_null,那么在这种情况下为什么不直接使用原始指针呢?

c++ notnull stdoptional

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

C++标准是否允许在没有开销的情况下实现std :: optional <double>

我刚刚看了cppcon谈论Bloomberg数据,这种变体类型使用IEEE754格式的冗余来编码存储在数据中的类型.

所以我想知道C++标准是否允许实现通过使用相同的技巧更有效地实现std :: optional.

请注意,这将要求有时存储在optional中的double的二进制表示与传递给构造函数的double的二进制表示不匹配.

注意:我关心标准允许这个与否,我知道大多数/所有实现都不会打扰.

我知道IEEE754不是标准规定的,但它是允许的,并且可以通过实现来检查.

c++ floating-point ieee-754 c++17 stdoptional

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

std::可选默认构造函数在 gcc 中不是 constexpr?

我有以下代码来测试我的 constexpr 可构造惰性类:

https://godbolt.org/z/rMLCiL

#include <optional>

template <class T>
class Lazy
{

    using initializer_t = T (*)();
    std::optional<T> m_val = std::nullopt;
    initializer_t m_initializer;

public:
    constexpr Lazy(initializer_t initializer = initializer_t{[] { return T{}; }}) noexcept
        : m_initializer{initializer} {}

    T& operator*()
    {
        if (!m_val.has_value()) {
            m_val = m_initializer();
        }
        return *m_val;
    }
    constexpr T* operator->() { return &(**this); }
};


#include <iostream>
struct A {
    int f() { return 10; }
    ~A()
    {
        std::cout << "Goodbye A " << (void*)this << std::endl; …
Run Code Online (Sandbox Code Playgroud)

c++ gcc initialization constexpr stdoptional

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

我可以以某种方式返回 std::Optional 并带有对我的数据的 const 引用以避免复制它吗?

假设我有一些基类,它可以选择返回一些特定的数据。它还为我提供了“hasData”函数来检查此类特定数据是否可供使用

class MyClassBase {
public:
    virtual bool hasData() const { return false; }
    virtual const Arg1& getData() const { throw std::runtime_error("No data");  }
};

class MyClassDerived: public MyClassBase {
    Arg1 m_data = Arg1(10);
public:
    bool hasData() const override { return true; }
    // Good - no copy constructor for data as I want
    const Arg1& getData() const override { return m_data; }
};
Run Code Online (Sandbox Code Playgroud)

这效果很好并且达到了我想要的效果。但是“hasData”和“getData”是很好的候选者,可以用一个返回“std::optional”的函数来替换。但是当我尝试改进返回 std::Optional 的 API 时,我意识到我无法再将“常量引用”返回到我的内部数据

class MyClassWithOptBase {
public:
    virtual std::optional<Arg1> getData() const { return std::nullopt; } …
Run Code Online (Sandbox Code Playgroud)

c++ stl c++17 stdoptional

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

我应该将值移出可选值还是移动整个可选值?

std::move(*optional)和之间有有效的区别吗*std::move(optional)?哪一个更可取?

完整示例:

#include <optional>
#include <vector>

void foo()
{
    std::optional<std::vector<int>> ov = std::vector<int>{};
    std::vector<int> v;
    v = std::move(*ov);
}

void bar()
{
    std::optional<std::vector<int>> ov = std::vector<int>{};
    std::vector<int> v;
    v = *std::move(ov);
}
Run Code Online (Sandbox Code Playgroud)

c++ move c++17 stdoptional

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

std::Optional 在构造过程中是否包含值?

查看以下代码作为示例:

#include <iostream>
#include <optional>

class A {
public:
    A();
    ~A();
};

std::optional<A> a;

A::A() { std::cout << a.has_value(); }
A::~A() { std::cout << a.has_value(); }

int main() {
    a.emplace();
    std::cout << a.has_value();
}
Run Code Online (Sandbox Code Playgroud)

我最终得到了类似的东西,并且惊讶地发现它a在构造函数中没有价值。这可能是一件好事,因为该对象尚未完全构建并且我的设计可以改进。但我没有在 cppreference 中找到任何关于它应该按照标准表现的证据。

所以我的问题是(主要是出于好奇):上面示例代码中的输出应该是什么,是指定的还是实现定义的(或 UB)?

有趣的是,上面的代码打印(剧透):

010对于 GCC 和 Cland,以及011MSVC。

c++ language-lawyer stdoptional

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

std::可选::使用 std::addressof 进行变换

考虑以下代码:

#include <memory>
#include <optional>

template <typename T>
constexpr T * arg_to_pointer(T & arg) noexcept {
    return std::addressof(arg);
}

int main() {
    std::optional<int> foo;

    auto * test = foo.transform(arg_to_pointer<int>).value_or(nullptr);
    //auto * test = foo.transform(std::addressof<int>).value_or(nullptr);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

未注释掉的行(将一个哑包装器std::addressof作为函数参数传递给std::optional::transform)可以编译并正常工作。被注释掉的行(尝试std::addressof直接使用的行)没有 - 我收到一条错误,指示模板参数推导失败(此处使用 GCC 13.2 的实时示例,尽管在 Clang 16.0 中观察到类似的行为)。为什么是这样?std::addressof标准和我周围的愚蠢包装有什么区别?

c++ stdoptional c++23

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