を条件:get()
コールでコンパイル時間の派遣:次のコードを考えると、有効なコール
template<typename GroupA, typename GroupB>
class JoinedObjectGroup
: public _ObjectSpaceHolder<GroupA>
, public _ObjectSpaceHolder<GroupB>
{
public:
JoinedObjectGroup(GroupA &groupA, GroupB &groupB)
: _ObjectSpaceHolder<GroupA>(groupA)
, _ObjectSpaceHolder<GroupB>(groupB)
{
}
template<typename ObjectType>
ObjectType get()
{
// Dispatch to appropriate handler: only one of the following actually compiles as
// either GroupA knows about ObjectType or GroupB, but not both. So:
//
// return static_cast<_ObjectSpaceHolder<GroupA> &>(*this).m_objectSpace.get<ObjectType>();
// or
// return static_cast<_ObjectSpaceHolder<GroupB> &>(*this).m_objectSpace.get<ObjectType>();
}
};
は、私は適切なハンドラにコンパイル時のディスパッチを実行したいと思います。その根底にある考え方は、ObjectType
がGroupA
またはGroupB
のいずれかであることです。
template<typename ObjectType>
ObjectType get()
{
return Dispatch<ObjectType, GroupA, GroupB>::get(*this);
}
で:私の最初のアプローチは、次のことをした
template<typename ObjectType, typename GroupA, typename GroupB, typename = void>
struct Dispatch;
template<typename ObjectType, typename GroupA, typename GroupB>
struct Dispatch<ObjectType, GroupA, GroupB, typename std::enable_if<std::is_same<ObjectType, decltype(std::declval<GroupA>().template get<ObjectType>())>::value>::type>
{
template<typename JoinedGroup>
static
ObjectType get(JoinedGroup &joinedGroup)
{
return static_cast<_ObjectSpaceHolder<GroupA> &>(joinedGroup).m_objectSpace.get<ObjectType>();
}
};
template<typename ObjectType, typename GroupA, typename GroupB>
struct Dispatch<ObjectType, GroupA, GroupB, typename std::enable_if<std::is_same<ObjectType, decltype(std::declval<GroupB>().template get<ObjectType>())>::value>::type>
{
template<typename JoinedGroup>
static
ObjectType get(JoinedGroup &joinedGroup)
{
return static_cast<_ObjectSpaceHolder<GroupB> &>(joinedGroup).m_objectSpace.get<ObjectType>();
}
};
私は、これはenable_if
のis_same
句でObjectType
を代入すると、式のいずれかが失敗につながると考え、したがって、残して働くだろうと想定していました1つの有効な専門化のみ。しかし、あいまいな名前や再定義エラーは私を間違っています。
なぜ私の推論は間違っていますか?代わりに、代わりに適切にコールをディスパッチできますか?
@JoachimPileborg:ありがとう、それは名前を単純化するときに導入されたタイプミスでした。これを修正しました。 – OnMyLittleDuck
また、 '_ObjectSpaceHolder'はコンパイラ用に予約されています(アンダースコア - 大文字で始まるすべての名前とともに)。 –
私は上記の仮定は、 'テンプレート T GroupA :: get ()'と 'テンプレート T GroupB :: get ()'のうちの1つだけが存在するということです。 –
Smeeheey