在元组中存储指向形参pack副本的指针



我想存储指向副本的指针参数包参数元组中。下面是代码:

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扩展了FDead,FBossAlive扩展了FAliveTContext使用基类型创建作为模板参数,但然后我发送我想要复制的子类型,然后在States元组中存储指向它们的指针。

我得到这个编译错误:

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

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

(new TSubStates{ InStates }, ...)

计算为initializer_list,而不是元组(因为逗号,我相信),但我不知道如何解决这个问题。任何帮助将非常感激!

的被害者。我需要存储副本,我不能改变构造函数签名来接受一组指针。

这里不需要折叠表达式。一个常规的参数包扩展就可以完成这个任务。

此外,虽然不是严格必要的你的例子张贴,使用std::forward<>时处理转发引用(其中InStates是)是一个好习惯进入。

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> && ...));
}

相关内容

  • 没有找到相关文章

最新更新