将指针存储到元组中的参数包的副本

发布于 2025-02-03 06:20:45 字数 1465 浏览 4 评论 0原文

我想在 tuple 中存储的指示 参数包参数。这是代码:

struct FDead {};
struct FAlive {};

struct FBossDead final : FDead {};
struct FBossAlive final : FAlive {};

template<typename... TStates>
struct TContext
{
    using FTuple = std::tuple<TStates*...>;
    
    template<typename... TSubStates>
    explicit TContext(TSubStates&&... InStates)
    {
        static_assert(sizeof...(TStates) == sizeof...(TSubStates));

        // FIXME: Check if TSubStates are actually sub-types of TStates
        //static_assert(((std::is_base_of_v<TStates, TSubStates> || ...) && ...));
    
        States = FTuple{(new TSubStates{ InStates }, ...)};
    }
    
    FTuple States;
};

void Test()
{
    TContext<FAlive, FDead> Context
    {
        FBossAlive{},
        FBossDead{}
    };
}

如您所见,fbossdead扩展了fdeadfbossalive扩展了falive> falivetcontext是用基本类型作为模板参数创建的代码>元组。

不过,我遇到了此汇编错误:

[C2440] '<function-style-cast>': cannot convert from 'initializer list' to 'std::tuple<PCF::SubClass::FAlive *,PCF::SubClass::FDead *>'

我相信这是因为此折叠表达式:

(new TSubStates{ InStates }, ...)

评估initarizer_list,而不是元组(由于逗号,我相信),但我不知道如何修复这个问题。任何帮助将不胜感激!

NB我需要存储副本,我无法更改构造函数签名以接受一包指针。

I want to store pointers to copies of parameter pack arguments in a tuple. Here is the code:

struct FDead {};
struct FAlive {};

struct FBossDead final : FDead {};
struct FBossAlive final : FAlive {};

template<typename... TStates>
struct TContext
{
    using FTuple = std::tuple<TStates*...>;
    
    template<typename... TSubStates>
    explicit TContext(TSubStates&&... InStates)
    {
        static_assert(sizeof...(TStates) == sizeof...(TSubStates));

        // FIXME: Check if TSubStates are actually sub-types of TStates
        //static_assert(((std::is_base_of_v<TStates, TSubStates> || ...) && ...));
    
        States = FTuple{(new TSubStates{ InStates }, ...)};
    }
    
    FTuple States;
};

void Test()
{
    TContext<FAlive, FDead> Context
    {
        FBossAlive{},
        FBossDead{}
    };
}

As you can see, FBossDead extends FDead, and FBossAlive extends FAlive. TContext is created with base types as template arguments but then I'm sending their subtypes that I want to copy and then store pointers to them in the States tuple.

I am getting this compilation error though:

[C2440] '<function-style-cast>': cannot convert from 'initializer list' to 'std::tuple<PCF::SubClass::FAlive *,PCF::SubClass::FDead *>'

I believe that's because of this fold expression:

(new TSubStates{ InStates }, ...)

that evaluates to a initializer_list, not a tuple (because of the comma, I believe) but I have no idea how to fix this problem. Any help will be much appreciated!

n.b. I need to store copies, I can not change the constructor signature to accept a pack of pointers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

み格子的夏天 2025-02-10 06:20:45

您在这里不需要折叠表达式。常规参数包扩展将可以很好地解决问题。

另外,尽管对于发布的示例并不是严格必要的,但是使用std :: forward&lt;&gt;在处理转发参考时(哪个intates is)是一个很好的习惯进入。

States = FTuple{ new TSubStates{ std::forward<TSubStates>(InStates) }... };

但是您不妨在初始化列表中执行此操作:

template<typename... TSubStates>
explicit TContext(TSubStates&&... InStates)
    : States{ new TSubStates{ std::forward<TSubStates>(InStates) }... } {

  // FIXED: Check if TSubStates are actually sub-types of TStates
  // But this is redundant, as the pointer assignment itself would fail.
  static_assert((std::is_base_of_v<TStates, TSubStates> && ...));
}

You don't need a fold expression here. A regular parameter pack expansion will do the trick just fine.

Also, while not strictly necessary for your example as posted, using std::forward<> when dealing with Forwarding References (which InStates is) is a good habit to get into.

States = FTuple{ new TSubStates{ std::forward<TSubStates>(InStates) }... };

But you might as well do it in the initializer list:

template<typename... TSubStates>
explicit TContext(TSubStates&&... InStates)
    : States{ new TSubStates{ std::forward<TSubStates>(InStates) }... } {

  // FIXED: Check if TSubStates are actually sub-types of TStates
  // But this is redundant, as the pointer assignment itself would fail.
  static_assert((std::is_base_of_v<TStates, TSubStates> && ...));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文