std::optional
From cppreference -std::optional
The class template std::optional manages an optional contained value, i.e. a value that may or may not be present.
A common use case for optional is the return value of a function that may fail. As opposed to other approaches, such as std::pair<T,bool>, optional handles expensive-to-construct objects well and is more readable, as the intent is expressed explicitly.
C++17标准库类模板 std::optional 管理一个可选的容纳值,这个值能存在也可能不存在。
一种比较常见的 optional 使用场景是一个可能失败的函数的返回值。和其他方式相比,如 std::pair<T,bool> , optional 良好地处理构造开销高昂的对象,并更加可读,因为它显式表达意图。
When an object of type optional is contextually converted to bool, the conversion returns true if the object contains a value and false if it does not contain a value.
一个类型为optional 的对象在函数中转换为bool时,如果该对象包含一个值,则转换返回true;如果该对象不包含一个值,则转换返回false。
optional<string> val = getString("std::optional");
if (val) //true
{
std::cout << *val << std::endl;
}
optional<string> valNull = getString();
if (valNull ) //false
{
std::cout << *val << std::endl;
}
std::optional是C++17引入,旧的版本我们可以自行实现。
template <typename T>
class Optional {
public:
Optional() = default;
Optional(const Optional &) = default;
Optional& operator=(const Optional &) = default;
Optional(Optional &&) = default;
Optional& operator=(Optional &&) = default;
~Optional() = default;
template <typename ...Args>
explicit Optional(Args &&...args) : _value(true, T(std::forward<Args>(args)...)) {}
explicit operator bool() const {
return _value.first;
}
T& value() {
return _value.second;
}
const T& value() const {
return _value.second;
}
T* operator->() {
return &(_value.second);
}
const T* operator->() const {
return &(_value.second);
}
T& operator*() {
return _value.second;
}
const T& operator*() const {
return _value.second;
}
private:
std::pair<bool, T> _value;
};
class StringView {
public:
constexpr StringView() noexcept = default;
constexpr StringView(const char *data, std::size_t size) : _data(data), _size(size) {}
StringView(const char *data) : _data(data), _size(std::strlen(data)) {}
StringView(const std::string &str) : _data(str.data()), _size(str.size()) {}
constexpr StringView(const StringView &) noexcept = default;
StringView& operator=(const StringView &) noexcept = default;
constexpr const char* data() const noexcept {
return _data;
}
constexpr std::size_t size() const noexcept {
return _size;
}
private:
const char *_data = nullptr;
std::size_t _size = 0;
};