将指向参数包副本的指针存储在元组中
Store pointers to copies of the parameter pack in a 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
扩展了 FDead
,FBossAlive
扩展了 FAlive
。 TContext
是使用 基本类型 作为模板参数创建的,但随后我发送了我想要复制的子类型,然后将指向它们的指针存储在 States
元组中.
不过我遇到了这个编译错误:
[C2440] '<function-style-cast>': cannot convert from 'initializer list' to 'std::tuple<PCF::SubClass::FAlive *,PCF::SubClass::FDead *>'
我相信这是因为这个折叠表达式:
(new TSubStates{ InStates }, ...)
计算结果为 initializer_list
,而不是元组(我相信是因为逗号),但我不知道如何解决此问题。任何帮助将不胜感激!
n.b。我需要存储副本,我不能更改构造函数签名来接受一组指针。
这里不需要折叠表达式。常规参数包扩展就可以解决问题。
此外,虽然对于您发布的示例而言并非绝对必要,但在处理转发引用时使用 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> && ...));
}
我想在元组中存储指向参数包参数的副本的指针。这是代码:
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
扩展了 FAlive
。 TContext
是使用 基本类型 作为模板参数创建的,但随后我发送了我想要复制的子类型,然后将指向它们的指针存储在 States
元组中.
不过我遇到了这个编译错误:
[C2440] '<function-style-cast>': cannot convert from 'initializer list' to 'std::tuple<PCF::SubClass::FAlive *,PCF::SubClass::FDead *>'
我相信这是因为这个折叠表达式:
(new TSubStates{ InStates }, ...)
计算结果为 initializer_list
,而不是元组(我相信是因为逗号),但我不知道如何解决此问题。任何帮助将不胜感激!
n.b。我需要存储副本,我不能更改构造函数签名来接受一组指针。
这里不需要折叠表达式。常规参数包扩展就可以解决问题。
此外,虽然对于您发布的示例而言并非绝对必要,但在处理转发引用时使用 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> && ...));
}