通过 API 填写"std::optional"<T>,获取输出"T*"参数
Filling `std::optional<T>` via API taking output `T*` parameter
我有一个传统的非阻塞取消排队API,如下所示:
template <typename T>
bool bad_queue<T>::try_dequeue(T* out);
// Returns 'false' if there was nothing to dequeue.
// Returns 'true' and sets '*out' to the dequeued item otherwise.
我想将bad_queue<T>
包装到我自己的cool_queue<T>
中,它从其try_dequeue
成员函数返回一个std::optional<T>
:
template <typename T>
class cool_queue
{
private:
bad_queue<T> _q;
public:
std::optional<T> try_dequeue();
};
这是我目前实现try_dequeue
的方式:
template <typename T>
std::optional<T> cool_queue<T>::try_dequeue()
{
T temp;
const auto ok = _q.try_dequeue(&temp);
if(!ok) { return std::nullopt; }
return {std::move(temp)};
}
有没有办法避免临时temp
缓冲区并直接构造_q.try_dequeue
在可选中返回的值?例:
// PSEUDOCODE
template <typename T>
std::optional<T> cool_queue<T>::try_dequeue()
{
std::optional<T> temp;
const auto ok = _q.try_dequeue(&temp.storage());
if(!ok) { return std::nullopt; }
temp.assume_has_object();
return temp;
}
你不能通过指针真正构造可选的值,但你的遗留 API 无论如何都不允许这样做。相反,您可以在 optional 中默认构造一个值,并将指针传递给该值:
template <typename T>
std::optional<T> cool_queue<T>::try_dequeue()
{
std::optional<T> temp;
const auto ok = _q.try_dequeue(&temp.emplace());
if (!ok) { temp.reset(); }
return temp;
}
从您的描述来看,旧版try_dequeue
函数似乎没有任何初始化为目标对象分配的内存的责任("...将"*out
'设置为 ...">),因此需要在旧版(可能是对象分配)调用之前构造目标对象。具体来说,对于目标对象是std::optional
实例包装的值,如果我们要访问其地址,该实例必须包含一个(包装的)值。
如果std::optional
的观察者不包含值,则对 ([optional.observe]) 的要求隐式指定 UB;如果*someOptional
不包含值;从 [optional.optional]/1 开始:
任何给定时间的任何
optional<T>
实例都包含 值或不包含值。当一个实例可选 包含一个值,表示 T 类型的对象,称为 可选对象的包含值在存储中分配 的可选对象。
绕过此问题的唯一方法是更改旧版 API。
正如@Casey的注释中所述,您可以就地对目标对象进行值初始化,并相应地重构cool_queue<T>::try_dequeue()
,例如:
template <typename T>
std::optional<T> cool_queue<T>::try_dequeue()
{
std::optional<T> temp{std::in_place};
return _q.try_dequeue(&*temp) ? temp : std::nullopt;
}
相关文章:
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- C++输出参数与返回值
- C++具有模板成员变量的类. 和参数内存输出
- 重载 ostream << 运算符,指针作为参数,导致输出上的内存地址
- C++函子作为函数的输出参数
- isPalindrome不显示输出,isPalindrome函数未使用字符串输入作为字符串参数进行测试
- 将ctypes c_void_p强制转换为c输出参数
- 用输出参数包装一个c++函数,以便在javascript/node中使用
- GCC 仪器 - 是否可以自动输出函数的参数?
- 我可以将函数的输出参数存储到unique_ptr中吗?
- 在存在错误代码的情况下输出参数与 NRVO
- 如何传递unique_ptr<T>代替原始*输出*指针参数?
- windres 致命错误:将输出写入时:参数无效
- 基于对函数的参数调用流输出运算符的能力重载函数
- 具有输出参数的QT InvoKeMethod调用函数
- basic_string::替换的超出范围异常,而在范围内,正如调试相同参数的输出所证明的那样
- 将具有std ::向量的C 函数称为Julia的输入和输出参数
- C ShellexeCuteex不会通过未从该EXE产生输出来执行参数
- Can std :: make_unique将功能的输出作为参数
- 当将对象传递给具有参数作为引用类型的函数以及当其类对象类型时,会得到不同的输出