c++ - 在完美转发函数中公开参数类型,避免代码重复
问题描述
我有一个烦人的场景,我需要推迟一些对象的初始化state
并允许用户按需构造一个。例如
// user code
context c;
// ...do something...
c.initialize_state(a, b, c);
// library code
class context
{
private:
class state
{
state(A a, B b, C c);
state(const state&) = delete;
state(state&&) = delete;
};
std::optional<state> _state; // or `boost::optional`
public:
template <typename... Xs>
void initialize_state(Xs&&... xs)
{
_state.emplace(std::forward<Xs>(xs)...);
}
};
从上面的代码可以看出, 的界面并没有context::initialize_state
告诉用户如何初始化。用户被迫查看的实现,然后查看以了解应该传递给的内容。context::_state
initialize_state
state::state
initialize_state
我可以换成initialize_state
...
void initialize_state(A&& a, B&& b, C&& c)
{
_state.emplace(std::move(a), std::move(b), std::move(c));
}
...但这有一个主要缺点:存在代码重复state::state
,需要手动维护,以防参数类型发生变化。
有什么方法可以让我两全其美(干燥和用户友好的界面)?请注意,这state
是不可移动/可复制的。
解决方案
该类state
可能不可复制/可移动,但似乎A
,B
和C
是。(所以我假设还有一些其他的内部数据state
阻止了可复制性/可移动性)
您可以将这些成员拉出到另一个可以注入的类中state
。由于缺乏更好的名称,我将其命名为state_args
:
struct state_args
{
explicit state_args(A a, B b, C c);
A a_;
B b_;
C c_;
};
这启用了以下功能:
class context
{
private:
class state
{
state(state_args args);
state(const state&) = delete;
state(state&&) = delete;
};
std::optional<state> _state; // or `boost::optional`
public:
template<class STATE_ARGS, /*enable_if to ensure STATE_ARGS is indeed state_args*/>
void initialize_state(STATE_ARGS&& internal_state)
{
_state.emplace(std::forward<STATE_ARGS>(internal_state));
}
};
推荐阅读
- javascript - 无法设置未定义或空引用的属性“包装”
- r - 带有 CheckboxInput 的 R 闪亮过滤器
- nlp - 使用 T5 进行句子嵌入
- python - 类型错误:python 中不可散列的字典,同时减去两个字典中的值
- python - Python中三角分布的蒙特卡罗模拟
- python - 使用 mysql.connector 插入外键关系的更好方法是什么?
- powershell - 在powershell中格式化带有列的文本文件
- reactjs - Gutenberg 块:显示 HTML 标签的 RichText 默认值
- python - 我过滤素数的功能是打印重复项,我该如何解决?
- html - has-popup="true" on
- 还是?