Biorąc pod uwagę następujący fragment kodu:czasie kompilacji wysyłkowy: uzależnione od ważnej rozmowy
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>();
}
};
W zaproszeniu get()
, chciałbym wykonać w czasie kompilacji wysyłkę do odpowiedniej obsługi. Podstawową ideą jest to, że ObjectType
jest znane albo przez GroupA
lub przez GroupB
. Moje pierwsze podejście było następujące:
template<typename ObjectType>
ObjectType get()
{
return Dispatch<ObjectType, GroupA, GroupB>::get(*this);
}
z:
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>();
}
};
przypuszczałem to będzie działać myśląc, że zastąpienie ObjectType
w klauzuli enable_if
is_same
doprowadzi jedno z wyrażeń na niepowodzenie, a zatem pozostawiając tylko jedna ważna specjalizacja. Jednak niejednoznaczne nazwy i błędy re-definition mnie źle.
Dlaczego moje rozumowanie jest nieprawidłowe? Jak mogę zamiast tego poprawnie wysłać połączenie?
@JoachimPileborg: Dzięki, to była literówka wprowadzona podczas upraszczania imion. Naprawiono to. – OnMyLittleDuck
Należy również zauważyć, że '_ObjectSpaceHolder' jest zarezerwowany dla kompilatora (wraz ze wszystkimi nazwami, które rozpoczynają podkreślenie-litera Capital). –
Domyślam się, że powyższym założeniem jest, że tylko jeden z 'szablonu T GroupA :: get ()' i 'template T GroupB :: get ()' istnieje - czy to na pewno prawda? –
Smeeheey