das folgende Stück Code Gegeben:Compile Zeit Versand: abhängig gültigen Aufruf
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>();
}
};
Im get()
Anruf, würde Ich mag eine Kompilierung Absendung an den entsprechenden Handler auszuführen. Die zugrunde liegende Idee ist, dass ObjectType
entweder durch GroupA
oder GroupB
bekannt ist. Mein erster Ansatz war die folgende:
template<typename ObjectType>
ObjectType get()
{
return Dispatch<ObjectType, GroupA, GroupB>::get(*this);
}
mit:
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>();
}
};
ich angenommen hatte nachgedacht funktionieren würde, dass ObjectType
in der is_same
Klausel enable_if
Substitution einer der Ausdrücke führen würde zu scheitern und deshalb verlassen nur eine einzige gültige Spezialisierung. Mehrdeutige Namen und Neudefinitionsfehler beweisen mich jedoch falsch.
Warum ist meine Argumentation falsch? Und wie kann ich den Anruf stattdessen richtig versenden?
@JoachimPileborg: Danke, das war ein Schreibfehler bei der Vereinfachung der Namen. Das Problem wurde behoben. – OnMyLittleDuck
Beachten Sie auch, dass '_ObjectSpaceHolder' für den Compiler reserviert ist (zusammen mit allen Namen, die Unterstrich-Großbuchstaben beginnen). –
Ich nehme an, die Annahme in der obigen ist, dass nur eine der folgenden Vorlagen T GroupA :: get () 'und' template T GroupB :: get () 'exists - ist das definitiv wahr? –
Smeeheey