gpt4 book ai didi

c++ - 在完美转发函数中公开参数类型,避免代码重复

转载 作者:可可西里 更新时间:2023-11-01 15:22:16 25 4
gpt4 key购买 nike

我有一个烦人的场景,我需要推迟某些对象 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 的接口(interface)没有告诉用户如何初始化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 存在代码重复,需要手动维护以防参数类型发生变化。

有什么方法可以两全其美(DRY 和用户友好的界面)?请注意,state 不可移动/不可复制。

最佳答案

state 可能不可复制/移动,但看起来 ABC是。 (所以我假设 state 中还有其他一些内部数据会阻止可复制性/可移动性)

您可以将这些成员拉出到另一个可以注入(inject)到 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));
}
};

关于c++ - 在完美转发函数中公开参数类型,避免代码重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50369589/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com