如何知道类型时如何调用std :: forward

时间:2014-11-11 15:19:05

标签: c++ c++11 reference const move-semantics

我有以下代码:

class Game {
private:
    const Ruleset& rules;
public:
    Game(const Ruleset&);
}

public class Ruleset {
public:
    virtual ~Ruleset();
    virtual bool isMoveValid(Move&) const = 0;
}

现在,以下initilializer工作正常:

Game::Game(const Ruleset& r) : rules(r) {}

但我发现这并没有保护我免受悬挂对临时工的引用。我想到了以下解决方案:

class Game {
private:
    const Ruleset& rules;
public:
    Game(const Ruleset&);
    Game(const Ruleset&&) = delete;
}

这段代码的问题在于我在游戏中有很多构造函数的变体,我希望避免删除其他每一个,所以我想要像

这样的东西
class Game {
private:
    const Ruleset rules;
public:
    Game(const Ruleset&&);
}

Game::Game(const Ruleset& r) : rules(forward(r)) {}

可能有更多复制/移动的参数。假设我有一个带有4个参数的构造函数:

Constructor(type1&, type2&, type3&, type4&).

然后我想在可能的情况下使用move-constructor,但我不想编码Constructor的每个变体(type1&&,type2&,type3&,type4&)等......

这可能吗? (当然,Ruleset类必须现在声明移动构造函数)。当你有一个更好的解决问题的方法时,也要指出,这有助于我有效地编写这个类。

1 个答案:

答案 0 :(得分:1)

如果你只想接受左值,你可以写一个这样做的构造函数:

Game(RuleSet& r)
: rules(r)
{ }

这样你就不能轻易传递临时状态了,你仍然可以const&接受传递的内容。

您也可以通过通用引用获取每个参数并逐个转发每个参数。这也会隐藏const方面并强制您的rules成员成为const RulesSet*而不是参考:

template <typename Arg1, typename Arg2>
Game(Arg1&& a1, Arg2&& a2)
{
    initRulesSet(std::forward<Arg1>(a1));
    initSomethingElse(std::forward<Arg2>(a2));
}

void initRulesSet(RulesSet&& ) = delete;
void initRulesSet(const RulesSet& rs) { rules = &rs; }