将非可选变量分配给 std::optional 变量

Assigning a non optional variable to std::optional variable

我有一个 class,其中有一个声明为 void const * 的可选字段(我也很困惑 * 是在尖括号外还是在尖括号内。

class Test {
protected:
    std::optional<void const> *_data;  // void const *_data
public:
    explict Test(void const *data = nullptr);
}

在 Test.cpp 文件中。

Test(const void *data) {
    this->_data = data; // error
}

在您的示例中,_data 是指向 std::optional 的非常量指针(std::optional 持有 const void 类型无关紧要) ,您正在尝试将指向 const 对象(未知 void 类型)的指针分配给非常量指针。

这违反了 class 构造函数的约定,您承诺不修改指向的对象(不仅在构造函数中,而且永远不会)。考虑这个简化的例子:

template <typename T>
Test {
protected:
    T* _data;

public:
    explict Test(const void * data = nullptr) {
        _data = data; // ERROR: can't assign a const-pointer to a non-const pointer
    }
}

您的问题与std::optional无关。

考虑到您甚至可能不需要将指针包装在 std::optional 中,因为指针已经具有 nullptr:

的自然可空概念
class Test {
protected:
    const void* _data;
public:
    explict Test(void const *data = nullptr) {
        _data = data;
    }

    void do_thing() const {
        if (_data) { // nullable semantics naturally work on pointers, no need for `std::optional`
        // UNLESS `nullptr` isn't "null enough" for your application
            // do (const-qualified) operation on _data.
        }
    }
}

关于std::optional、指针和可为空的概念

it's the responsibility of the caller of the function to check for the null for the returned value

正确 - 您的用户无论如何都必须使用 std::optional

另一种选择是指定 class 的用户使用 nullptr 构建它是“未定义的行为”或“非法的”。并且对象以 nullptr 存在不是有效状态。这将责任转移到对象的“创建者”,而不是“用户”(即使他们可能是同一个人)。这完全取决于您的 _data 是否有效为 nullptr

决定允许对象的有效状态是什么,以及由谁负责执行该状态。如果您正确设计界面,则可以消除大量 if 检查,否则这些检查需要分散在代码的所有层中。

一些责任由对象创建者(用户)承担,一些责任由 class 承担(这可以与用户创建者共享以进行有效性检查,或忽略),还有一些与对象用户(应用程序开发人员)有关。