c++ - 类型已知时如何调用 std::forward

标签 c++ c++11 reference constants move-semantics

我有以下代码:

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

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

现在下面的初始化器工作正常:

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

但我刚刚发现这并不能保护我免受对临时对象的悬空引用。我想到了以下解决方案:

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

这段代码的问题是我在现实中有很多 Game 构造函数的变体,我想避免专门删除每个其他构造函数,所以我想要类似的东西

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

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

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

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

然后我想尽可能使用 move-constructor,但我不想编写 Constructor(type1&&、type2&、type3&、type4&)等的每个变体......

这可能吗? (当然,规则集类现在必须声明 move 构造函数)。还要指出您何时有更好的方法来帮助我有效地编写此类代码。

最佳答案

如果你只想接受左值,你可以只写一个构造函数来实现:

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

这样你就不能轻易地传入临时变量,你仍然可以对传递的内容使用 const&

您还可以通过 universal ref 获取每个参数,然后逐个转发每个参数。这也将隐藏 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; }

关于c++ - 类型已知时如何调用 std::forward,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26868175/

相关文章:

c++ - 内部静态和捕获的可变之间的 Lambda 状态行为差异

ruby-on-rails - Ruby 对象引用

c++ - pthread_kill() 与 pthread_cancel() 终止因 I/O 而阻塞的线程

c++ - C++ 的模块标准是否解决了对调用者隐藏私有(private)数据的问题?

c++ - 使用 std::initializer_list 创建树?

c++使用模板制作最通用的函数

c# - Visual Studio 添加控制台应用程序作为引用

C 指针和内存分配 : Realloc Arrays and Pointer Passing

c++ - 如何使用重新定义的打印功能打印 Lua 表?

c++ - std::list 提示缺少第二个模板参数(分配器)