翻蚳è
ããïŒããã¯ãQt 5ã®ä¿¡å·ãšã¹ãããã®å
éšã¢ãŒããã¯ãã£ã«é¢ããOlivier Goffartã«ããèšäºã®ç¿»èš³ã®ç¬¬2éšã§ã ã第1éšã®ç¿»èš³ã¯ãã¡ãã§ããQt5ã®æ°ããæ§æ
æ°ããæ§æã¯æ¬¡ã®ããã«ãªããŸãã
QObject::connect(&a, &Counter::valueChanged, &b, &Counter::setValue);
ãã®æçš¿ã§ã¯ãæ°ããæ§æã®å©ç¹ã«ã€ããŠæ¢ã«èª¬æããŸããã ã€ãŸããæ°ããæ§æã§ã¯ãã³ã³ãã€ã«æã«ä¿¡å·ãšã¹ãããããã§ãã¯ã§ããŸãã åŒæ°ããŸã£ããåãã¿ã€ãã§ãªãå ŽåãåŒæ°ãèªåçã«å€æããããšãã§ããŸãã ãŸããããŒãã¹ãšããŠããã®æ§æã䜿çšãããšãã©ã ãåŒã䜿çšã§ããŸãã
æ°ãããªãŒããŒããŒãã¡ãœãã
ãããæ©èœããããã«å¿
èŠãªå€æŽã¯ãããã§ããã äž»ãªã¢ã€ãã¢ã¯ãæ°ããQObject ::æ¥ç¶ãªãŒããŒããŒãã§ããããã¯ãchar *ã§ã¯ãªãé¢æ°ãã€ã³ã¿ãŒãåŒæ°ãšããŠåãåããŸãã ãããã¯3ã€ã®æ°ããã¡ãœããïŒæ¬äŒŒã³ãŒãïŒã§ãã
QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType type); QObject::connect(const QObject *sender, PointerToMemberFunction signal, PointerToFunction method) QObject::connect(const QObject *sender, PointerToMemberFunction signal, Functor method)
æåã®æ¹æ³ã¯ãå€ãæ§æã«æãè¿ãæ¹æ³ã§ããéä¿¡åŽã®ä¿¡å·ãåä¿¡åŽã®ã¹ãããã«æ¥ç¶ããŸãã ä»ã®2ã€ã¯ãã®æ¥ç¶ããªãŒããŒããŒãããéçé¢æ°ãšã¬ã·ãŒããŒãªãã®ãã¡ã³ã¯ã¿ãŒãä¿¡å·ã«æ¥ç¶ããŸãã ãã¹ãŠã®æ¹æ³ã¯éåžžã«äŒŒãŠããããã®æçš¿ã§ã¯æåã®æ¹æ³ã®ã¿ãåæããŸãã
ã¡ã³ããŒé¢æ°ãã€ã³ã¿ãŒ
説æãç¶ããåã«ãã¡ã³ããŒé¢æ°ãžã®ãã€ã³ã¿ãŒã«ã€ããŠå°ãã話ãããããšæããŸãã 以äžã¯ãé¢æ°ãžã®ãã€ã³ã¿ãŒã宣èšããŠåŒã³åºãéåžžã«ç°¡åãªã³ãŒãã§ãã
ã¡ã³ããŒãã€ã³ã¿ãŒãšã¡ã³ããŒé¢æ°ãã€ã³ã¿ãŒã¯ãC ++ãµãã»ããã®äžè¬çãªéšåã§ãããããŸãäžè¬çã«äœ¿çšãããŠããªããããããŸãç¥ãããŠããŸããã è¯ããã¥ãŒã¹ã¯ãQtãšãã®æ°ããæ§æã䜿çšããããã«ããã«ã€ããŠç¥ãå¿
èŠããªãããšã§ãã èŠããŠããå¿
èŠãããã®ã¯ãæ¥ç¶ã®ä¿¡å·åã®åãšåã«é
眮ããå¿
èŠããããã®ã ãã§ãã éæ³ã®æŒç®å:: * ,. *ãŸãã¯-> *ãæ±ãå¿
èŠã¯ãããŸããã ãããã®éæ³ã®æŒç®åã䜿çšãããšãã¡ã³ããŒé¢æ°ãžã®ãã€ã³ã¿ãŒã宣èšããŠã¢ã¯ã»ã¹ã§ããŸãã ãã®ãããªãã€ã³ã¿ãŒã®åã«ã¯ãæ»ãå€ã®åãé¢æ°ãå±ããã¯ã©ã¹ããã¹ãŠã®åŒæ°ã®åãããã³é¢æ°ã®constæå®åãå«ãŸããŸãã
ã¡ã³ããŒé¢æ°ãžã®ãã€ã³ã¿ãŒã¯ãsizeofãç°ãªããããç¹ã«voidã«å€æããããšã¯ã§ããŸããã é¢æ°ã®ã·ã°ããã£ããããã«ç°ãªãå Žåãããé¢æ°ããå¥ã®é¢æ°ã«å€æããããšã¯ã§ããŸããã ããšãã°ã
voidïŒMyClass :: *ïŒïŒintïŒconstãã
voidïŒMyClass :: *ïŒïŒintïŒãžã®å€æãèš±å¯ãããŠããŸãã
ïŒreinterpret_castã§ãããè¡ãããšãã§ããŸãããæšæºã«åŸã£ãŠãæªå®çŸ©ã®åäœïŒæªå®çŸ©ã®åäœïŒ ïŒé¢æ°ãåŒã³åºãããšããå ŽåïŒã
ã¡ã³ããŒé¢æ°ãã€ã³ã¿ãŒã¯ãéåžžã®é¢æ°ãã€ã³ã¿ãŒã ãã§ã¯ãããŸããã éåžžã®é¢æ°ãã€ã³ã¿ãŒã¯ãåã«æ©èœã³ãŒããé
眮ãããŠããã¢ãã¬ã¹ãžã®ãã€ã³ã¿ãŒã§ãã ãã ããã¡ã³ããŒé¢æ°ãžã®ãã€ã³ã¿ãŒã«ã¯ãããå€ãã®æ
å ±ãä¿åããå¿
èŠããããŸããå€éç¶æ¿ã®å Žåãã¡ã³ããŒé¢æ°ã¯ä»®æ³ã§ãããé衚瀺ã®å Žåã¯ãªãã»ãããæã€ããšãã§ããŸãã ã¡ã³ããŒé¢æ°ãã€ã³ã¿ãŒã®sizeofã¯ãã¯ã©ã¹ã«å¿ããŠ
ç°ãªãå Žåã
ãããŸã ã ãã®ãããããããæäœããããã®ç¹å¥ãªã±ãŒã¹ãå¿
èŠã§ãã
åç¹æ§ã¯ã©ã¹ïŒQtPrivate :: FunctionPointer
ã¿ã€ãQtPrivate :: FunctionPointerã®ããããã£ã®ã¯ã©ã¹ã玹ä»ããŸãã ããããã£ã¯ã©ã¹ã¯åºæ¬çã«ããã®åã«é¢ããã¡ã¿ããŒã¿ãè¿ããã«ããŒã¯ã©ã¹ã§ãã Qtã®ããããã£ã¯ã©ã¹ã®å¥ã®äŸã¯
QTypeInfoã§ãã æ°ããæ§æã®å®è£
ã®ãã¬ãŒã ã¯ãŒã¯ã§ç¥ãå¿
èŠãããã®ã¯ãé¢æ°ãžã®ãã€ã³ã¿ã«é¢ããæ
å ±ã§ãã
template <typename T> struct FunctionPointerã¯ãã¡ã³ããŒãéããŠTã«é¢ããæ
å ±ãæäŸããŸãã
- ArgumentCount-é¢æ°ã®åŒæ°ã®æ°ãè¡šãæ°å€
- ãªããžã§ã¯ã-ååšããŸããã¡ã³ããŒé¢æ°ãžã®ãã€ã³ã¿ãŒã«å¯ŸããŠã®ã¿ãã¯ã©ã¹ã®typedefã§ããããã®ã¡ã³ããŒé¢æ°ãžã®ãã€ã³ã¿ãŒã§ãã
- åŒæ°-åŒæ°ã®ãªã¹ããã¡ã¿ããã°ã©ãã³ã°ãªã¹ãã®typedefãè¡šããŸã
- callïŒTïŒfunctionãQObject * receiverãvoid ** argsïŒ-æž¡ããããã©ã¡ãŒã¿ãŒã§é¢æ°ãåŒã³åºãéçé¢æ°
Qtã¯åŒãç¶ãC ++ 98ã³ã³ãã€ã©ããµããŒãããŠããŸããã€ãŸããæ®å¿µãªãããå¯å€æ°ã®åŒæ°ãæã€ãã³ãã¬ãŒãïŒvariadicãã³ãã¬ãŒãïŒã®ãµããŒããèŠæ±ããããšã¯ã§ããŸããã èšãæãããšãåŒæ°ã®æ°ããšã«ããããã£ã®ã¯ã©ã¹çšã«é¢æ°ãç¹æ®åããå¿
èŠããããŸãã 4ã€ã®ã¿ã€ãã®ç¹æ®åããããŸãïŒé¢æ°ãžã®éåžžã®ãã€ã³ã¿ãŒãã¡ã³ããŒé¢æ°ãžã®ãã€ã³ã¿ãŒãå®æ°ã¡ã³ããŒé¢æ°ãžã®ãã€ã³ã¿ãŒãããã³ãã¡ã³ã¯ã¿ãŒã ã¿ã€ãããšã«ãåŒæ°ã®æ°ããšã«ç¹æ®åãå¿
èŠã§ãã æ倧6ã€ã®åŒæ°ããµããŒãããŠããŸãã ã³ã³ãã€ã©ãå¯å€æ°ã®åŒæ°ãæã€ãã³ãã¬ãŒãããµããŒãããŠããå Žåãä»»æã®æ°ã®åŒæ°ã«å¯ŸããŠãå¯å€æ°ã®åŒæ°ãæã€ãã³ãã¬ãŒãã䜿çšããç¹æ®åããããŸãã FunctionPointerã®å®è£
ã¯
qobjectdefs_impl.hã«ãããŸãã
QObject ::æ¥ç¶
å®è£
ã¯å®åã³ãŒãã®å€ãã«äŸåããŸãã ããã«ã€ããŠã¯èª¬æããŸããã
qobject.hããã®æåã®æ°ãããªãŒããŒããŒãã®ã³ãŒãã¯æ¬¡ã®
ãšããã§ãã
template <typename Func1, typename Func2> static inline QMetaObject::Connection connect( const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot, Qt::ConnectionType type = Qt::AutoConnection) { typedef QtPrivate::FunctionPointer<Func1> SignalType; typedef QtPrivate::FunctionPointer<Func2> SlotType;
ããã¥ã¡ã³ãã«ç€ºãããŠããããã«ãéä¿¡è
ãšåä¿¡è
ã¯QObject *ã ãã§ã¯ãªãããšã«ãé¢æ°ã®çœ²åã§æ°ä»ããŸããã ãããã¯ãå®éã«ã¯typename FunctionPointer :: Objectãžã®ãã€ã³ã¿ãŒã§ãã ã¡ã³ãé¢æ°ãžã®ãã€ã³ã¿ã®ã¿ã«å«ãŸãããªãŒããŒããŒããäœæããã«ã¯ã
SFINAEã䜿çšããŸãã
ãã㯠ã
ObjectPoint㯠ãåãã¡ã³ãé¢æ°ãžã®ãã€ã³ã¿ã§ããå Žåã«ã®ã¿FunctionPointerã«ååšããããã§ãã
次ã«ãQ_STATIC_ASSERTã®æããå§ããŸãã ãŠãŒã¶ãŒãééããå Žåãæå³ã®ããã³ã³ãã€ã«ãšã©ãŒãçæããå¿
èŠããããŸãã ãŠãŒã¶ãŒãäœãééã£ãããšãããå Žåã¯ã_impl.hãã¡ã€ã«ã®ãã³ãã¬ãŒãã³ãŒãããŒãã«ã§ã¯ãªããããã§ãšã©ãŒã確èªããããšãéèŠã§ãã ãŠãŒã¶ãŒãå¿é
ããªãããã«ãå
éšå®è£
ãé衚瀺ã«ããå¿
èŠããããŸãã ããã¯ãå®è£
ã®è©³çŽ°ã«ç解ã§ããªããšã©ãŒã衚瀺ãããå Žåãå ±åããå¿
èŠããããšã©ãŒãšèŠãªãããããšãæå³ããŸãã
次ã«ãQSlotObjectã®ã€ã³ã¹ã¿ã³ã¹ãäœæããconnectImplïŒïŒã«æž¡ããŸãã QSlotObjectã¯ãã¹ãããã®åŒã³åºãã«åœ¹ç«ã€ã©ãããŒã§ãã 圌女ã¯ãŸããä¿¡å·åŒæ°ã®ã¿ã€ããç¥ã£ãŠãããé©åãªã¿ã€ãå€æãè¡ãããšãã§ããŸãã List_Leftã䜿çšããã®ã¯ãã¹ããããšåãæ°ã®åŒæ°ã®ã¿ãæž¡ãããã§ããããã«ãããä¿¡å·ãããåŒæ°ã®å°ãªãã¹ãããã«ä¿¡å·ãæ¥ç¶ã§ããŸãã
QObject :: connectImplã¯ãæ¥ç¶ãå®è¡ãããã©ã€ããŒãå
éšé¢æ°ã§ãã QObjectPrivate :: Connectionæ§é äœã«ã¡ãœããã€ã³ããã¯ã¹ãä¿åãã代ããã«ãQSlotObjectBaseãžã®ãã€ã³ã¿ãŒãä¿åãããšããéãã¯ãããŸãããå
ã®æ§æã«äŒŒãŠããŸãã
void **ãšããŠæž¡ããŠã¹ãããããçç±ã¯ãã¿ã€ããQt :: UniqueConnectionã®å Žåã«æ¯èŒã§ããããã«ããããã§ãã ãŸããvoid **ãšããŠæž¡ããŸãã ããã¯ãã¡ã³ããŒé¢æ°ãžã®ãã€ã³ã¿ãŒãžã®ãã€ã³ã¿ãŒã§ãã
ã·ã°ãã«ã€ã³ããã¯ã¹
ã·ã°ãã«ãã€ã³ã¿ãŒãšã·ã°ãã«ã€ã³ããã¯ã¹ãæ¥ç¶ããå¿
èŠããããŸãã ããã«ã¯
MOCã䜿çšããŸãã ã¯ããããã¯ããã®æ°ããæ§æããŸã
MOCã䜿çšããŠããããããåãé€ãèšç»ããªãããšãæå³ããŸã:-)ã
MOCã¯qt_static_metacallã§ã³ãŒããçæãããã©ã¡ãŒã¿ãŒãæ¯èŒããŠæ£ããã€ã³ããã¯ã¹ãè¿ããŸãã connectImplã¯ãé¢æ°ãã€ã³ã¿ãŒãžã®ãã€ã³ã¿ãŒã§qt_static_metacallé¢æ°ãåŒã³åºããŸãã
void Counter::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) { if (_c == QMetaObject::InvokeMetaMethod) { } else if (_c == QMetaObject::IndexOfMethod) { int *result = reinterpret_cast<int *>(_a[0]); void **func = reinterpret_cast<void **>(_a[1]); { typedef void (Counter::*_t)(int ); if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&Counter::valueChanged)) { *result = 0; } } { typedef QString (Counter::*_t)(const QString & ); if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&Counter::someOtherSignal)) { *result = 1; } } { typedef void (Counter::*_t)(); if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&Counter::anotherSignal)) { *result = 2; } } } }
ã·ã°ãã«ã€ã³ããã¯ã¹ãã§ããã®ã§ãåã®æ§æãšåæ§ã®æ§æã䜿çšã§ããŸãã
QSlotObjectBase
QSlotObjectBaseã¯ãã¹ããããåæ ããconnectImplã«æž¡ããããªããžã§ã¯ãã§ãã çŸåšã®ã³ãŒãã衚瀺ããåã«ãQObject :: QSlotObjectBaseã瀺ããŸããããã¯Qt5ã¢ã«ãã¡çã§ããïŒ
struct QSlotObjectBase { QAtomicInt ref; QSlotObjectBase() : ref(1) {} virtual ~QSlotObjectBase(); virtual void call(QObject *receiver, void **a) = 0; virtual bool compare(void **) { return false; } };
ããã¯åºæ¬çã«ãé¢æ°ãã€ã³ã¿ãŒã®åŒã³åºããšæ¯èŒãå®è£
ãããã³ãã¬ãŒãã¯ã©ã¹ãä»ããŠåå®è£
ãããããã«èšèšãããã€ã³ã¿ãŒãã§ã€ã¹ã§ãã ããã¯ããã³ãã¬ãŒãã¯ã©ã¹QSlotObjectãQStaticSlotObjectããŸãã¯QFunctorSlotObjectã®ããããã«ãã£ãŠå®è£
ãããŸãã
åœã®ä»®æ³ããŒãã«
åé¡ã¯ããã®ãããªãªããžã§ã¯ããã€ã³ã¹ã¿ã³ã¹åãããã³ã«ãä»®æ³é¢æ°ãžã®ãã€ã³ã¿ã ãã§ãªãã
RTTIãªã©ã®å¿
èŠã®ãªãå€ãã®æ
å ±ãå«ãä»®æ³ããŒãã«ãäœæããå¿
èŠãããããšã§ãã ããã¯ã倧éã®åé·ããŒã¿ãšãã€ããªãã¡ã€ã«ã®æ¥å¢ã«ã€ãªãããŸãã ãããåé¿ããããã«ãQSlotObjectBaseã¯ããªã¢ãŒãã£ãã¯ã¯ã©ã¹ã§ã¯ãªãããã«å€æŽãããŸããã ä»®æ³æ©èœã¯æåã§ãšãã¥ã¬ãŒããããŸãã
class QSlotObjectBase { QAtomicInt m_ref; typedef void (*ImplFn)(int which, QSlotObjectBase* this_, QObject *receiver, void **args, bool *ret); const ImplFn m_impl; protected: enum Operation { Destroy, Call, Compare }; public: explicit QSlotObjectBase(ImplFn fn) : m_ref(1), m_impl(fn) {} inline int ref() Q_DECL_NOTHROW { return m_ref.ref(); } inline void destroyIfLastRef() Q_DECL_NOTHROW { if (!m_ref.deref()) m_impl(Destroy, this, 0, 0, 0); } inline bool compare(void **a) { bool ret; m_impl(Compare, this, 0, a, &ret); return ret; } inline void call(QObject *r, void **a) { m_impl(Call, this, r, a, 0); } };
m_implã¯ã以åã®ä»®æ³é¢æ°ã§ãã£ã3ã€ã®æäœãå®è¡ããéåžžã®é¢æ°ãã€ã³ã¿ãŒã§ãã ç¹°ãè¿ãå®è£
ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã§æ©èœããããã«èšå®ãããŸãã
ããªãã¯ãããè¯ãããšãèªãã ã®ã§ãããªãã®ã³ãŒãã«æ»ã£ãŠãã®æ¹æ³ã§ãã¹ãŠã®ä»®æ³é¢æ°ãå€æŽããå¿
èŠã¯ãããŸããã ã»ãšãã©ãã¹ãŠã®æ¥ç¶åŒã³åºããæ°ããç°ãªãã¿ã€ããçæãããããããã¯ãã®å Žåã«ã®ã¿è¡ãããŸãïŒQSsignObjectããéå§ããã·ã°ãã«ã·ã°ããã£ãšã¹ãããã«äŸåãããã³ãã¬ãŒããã©ã¡ãŒã¿ããããŸãïŒã
ä¿è·ããããéãããéããä¿¡å·
ã·ã°ãã«ã¯Qt4以åã§ä¿è·ãããŠããŸããã ãªããžã§ã¯ãã®ç¶æ
ãå€åãããšãã«ä¿¡å·ããªããžã§ã¯ãããéä¿¡ããããã«èšèšããããšãéžæããŸããã ãããã¯ãªããžã§ã¯ãã®å€éšããåŒã³åºãããã¹ãã§ã¯ãªããä»ã®ãªããžã§ã¯ãããã·ã°ãã«ãåŒã³åºãããšã¯ã»ãšãã©åžžã«æªãèãã§ãã
ãã ããæ°ããæ§æã䜿çšãããšãæ¥ç¶ãäœæããæç¹ã§ä¿¡å·ã¢ãã¬ã¹ãååŸã§ããã¯ãã§ãã ã³ã³ãã€ã©ã¯ãã·ã°ãã«ã«ã¢ã¯ã»ã¹ã§ããå Žåã«ã®ã¿ãããèš±å¯ããŸãã æžã蟌ã¿ãšã«ãŠã³ã¿ãŒ:: valueChangedã¯ãä¿¡å·ãéããŠããªãå Žåãã³ã³ãã€ã«ãšã©ãŒãçæããŸãã
Qt5ã§ã¯ãä¿¡å·ãä¿è·ãããªãŒãã³ã«å€æŽããå¿
èŠããããŸããã æ®å¿µãªãããããã¯èª°ã§ãä¿¡å·ãçºä¿¡ã§ããããšãæå³ããŸãã ãããä¿®æ£ããæ¹æ³ãèŠã€ãããŸããã§ããã ç§ãã¡ã¯ã
emitããŒã¯ãŒãã䜿ã£ãŠããªãã¯ãè©ŠããŸããã ç¹å¥ãªæå³ãè¿ãããšããŸããã ããããäœãããŸããããŸããã§ããã æ°ããæ§æã®å©ç¹ã¯ãä¿¡å·ãçŸåšéããŠãããšãã®åé¡ãå
æãããšä¿¡ããŠããŸãã
å Žåã«ãã£ãŠã¯ãä¿¡å·ãéããããšããå§ãããŸãã ããã¯ãããšãã°QAbstractItemModelã®å Žåã§ããããã§ãªãå Žåãéçºè
ã¯APIãå¿
èŠãšããªã掟çã¯ã©ã¹ã§ä¿¡å·ãéä¿¡ããåŸåããããŸãã 圌ãã¯ãä¿¡å·ãéããããªããã»ããµããªãã¯ã䜿çšããŸããããæ°ããæ¥ç¶æ§æãç ŽããŸããã
æ°ããããã¯ãå°å
¥ãããŸããã QPrivateSignalã¯ãQ_OBJECTãã¯ãã§éããããŠãããšå®£èšããã空ã®æ§é ã§ãã ä¿¡å·ã®æåŸã®ãã©ã¡ãŒã¿ãŒãšããŠäœ¿çšã§ããŸãã éããããŠããã®ã§ããªããžã§ã¯ãã ããã·ã°ãã«ãåŒã³åºãããã«ãããäœæããæš©å©ãæã£ãŠããŸãã
MOC㯠ã眲åæ
å ±ãäœæãããšãã«æåŸã®QPrivateSignalåŒæ°
ãç¡èŠããŸãã äŸã«ã€ããŠã¯ã
qabstractitemmodel.hãåç
§ããŠãã ããã
ããå®åçãªã³ãŒã
æ®ãã®ã³ãŒãã¯
qobjectdefs_impl.hããã³
qobject_impl.hã«ãããŸãã ããã¯åºæ¬çã«éå±ãªå®åã³ãŒãã§ãã ãã®æçš¿ã®è©³çŽ°ã«ã€ããŠã¯è©³ãã説æããŸããããèšåãã䟡å€ã®ããããã€ãã®ãã€ã³ãã«ã€ããŠã¯èª¬æããŸãã
ã¡ã¿ããã°ã©ãã³ã°ãªã¹ã
åè¿°ã®ããã«ãFunctionPointer :: Argumentsã¯åŒæ°ã®ãªã¹ãã§ãã ã³ãŒãã¯ãã®ãªã¹ãã§æ©èœããå¿
èŠããããŸããèŠçŽ ããšã«èŠçŽ ãå埩ãããããã®äžéšã®ã¿ãååŸãããããã®èŠçŽ ãéžæããŸãã ããããQtPrivate :: Listãåã®ãªã¹ããšããŠè¡šçŸã§ããçç±ã§ãã ããã€ãã®ãã«ããŒã¯ã©ã¹ã¯QtPrivate :: List_Selectããã³QtPrivate :: List_Leftã§ãããããã¯ããªã¹ãã®Nçªç®ã®èŠçŽ ãšæåã®Nåã®èŠçŽ ãå«ããªã¹ãã®äžéšãè¿ããŸãã
Listã®å®è£
ã¯ãå¯å€æ°ã®ãã©ã¡ãŒã¿ãŒãæã€ãã³ãã¬ãŒãããµããŒããããããããµããŒãããªãã³ã³ãã€ã©ãŒã§ã¯ç°ãªããŸãã å¯å€æ°ã®ãã©ã¡ãŒã¿ãŒãæã€ãã³ãã¬ãŒãã®å ŽåïŒ
template<typename... T> struct List;
åŒæ°ãªã¹ãã¯ãåã«ãã³ãã¬ãŒããã©ã¡ãŒã¿ãé衚瀺ã«ããŸãã ããšãã°ãåŒæ°ïŒintãQstringãQObject *ïŒãå«ããªã¹ãã®ã¿ã€ãã¯æ¬¡ã®ããã«ãªããŸãã
List<int, QString, QObject *>
å¯å€æ°ã®ãã©ã¡ãŒã¿ãŒãæã€ãã³ãã¬ãŒãããªãå Žåãããã¯LISPã¹ã¿ã€ã«ã«ãªããŸãã
template<typename Head, typename Tail > struct List;
Tailã¯ããªã¹ãã®æåŸã«ããä»ã®ãªã¹ããŸãã¯ç¡å¹ã«ããããšãã§ããŸãã ãã®å Žåã®åã®äŸã¯æ¬¡ã®ããã«ãªããŸãã
List<int, List<QString, List<QObject *, void>>>
ApplyReturnValueããªãã¯
FunctionPointer :: callé¢æ°ã§ã¯ãargs [0]ã䜿çšããŠã¹ãããã®æ»ãå€ãååŸããŸãã ã·ã°ãã«ãå€ãè¿ãå Žåãããã¯ã·ã°ãã«ã®æ»ãå€ã®åãæã€ãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒã«ãªããŸããããã§ãªãå Žåã¯0ã§ããã¹ããããå€ãè¿ãå Žåããããarg [0]ã«ã³ããŒããå¿
èŠããããŸãã ç¡å¹ã®å ŽåãäœãããŸããã
åé¡ã¯ãvoidãè¿ãé¢æ°ã®æ»ãå€ã䜿çšããããšã¯æ§æçã«æ£ãããªãããšã§ãã 倧éã®ã³ãŒããè€è£œããå¿
èŠããããŸãã1åã¯voidã®æ»ãå€çšã§ããã1ã€ã¯void以å€ã®å€çšã§ãã ããããã³ã³ãæŒç®åã®ãããã§ãã
C ++ã§ã¯ããããè¡ãããšãã§ããŸãã
functionThatReturnsVoid(), somethingElse();
ã³ã³ããã»ãã³ãã³ã«çœ®ãæããããšãã§ããããã¯ãã¹ãŠçŽ æŽãããããšã§ãã void以å€ã§åŒã³åºããšèå³æ·±ããã®ã«ãªããŸãã
functionThatReturnsInt(), somethingElse();
ããã§ã¯ãã³ã³ããåŒã³åºãããã¹ããŒãã¡ã³ãã«ãªãããªãŒããŒããŒãããããšãã§ããŸãã ããã¯ã
qobjectdefs_impl.hã§è¡ãããš
ã§ã ã
template <typename T> struct ApplyReturnValue { void *data; ApplyReturnValue(void *data_) : data(data_) {} }; template<typename T, typename U> void operator,(const T &value, const ApplyReturnValue<U> &container) { if (container.data) *reinterpret_cast<U*>(container.data) = value; } template<typename T> void operator,(T, const ApplyReturnValue<void> &) {}
ApplyReturnValueã¯ãåãªãvoid *ã®ã©ãããŒã§ãã çŸåšãããã¯ç®çã®ãã«ããŒãšã³ãã£ãã£ã§äœ¿çšã§ããŸãã åŒæ°ãªãã®ãã¡ã³ã¯ã¿ãŒã®äŸã次ã«ç€ºããŸãã
static void call(Function &f, void *, void **arg) { f(), ApplyReturnValue<SignalReturnType>(arg[0]); }
ãã®ã³ãŒãã¯ã€ã³ã©ã€ã³ã§ãããããå®è¡æã®ããã©ãŒãã³ã¹ã«é¢ããŠã¯äœãããããŸããã