class __declspec(uuid("B372C9F6-1959-4650-960D-73F20CD479BA")) Class;
struct __declspec(uuid("B372C9F6-1959-4650-960D-73F20CD479BB")) Interface;
void test()
{
CLSID clsid=__uuidof(Class);
IID iid=__uuidof(Interface);
...
}
銆銆榪欐瘮璧蜂綘浠ュ墠瀹氫箟uuid鐨勬柟娉曠畝鍗曞浜嗗惂錛熷彲鎯滐紝榪欐牱濂界敤鐨勪笢瑗匡紝瀹冨彧鍦╒C++涓彁渚涖備笉榪囨病鏈夊叧緋伙紝鎴戜滑榪欓噷浠嬬粛涓涓妧宸э紝鍙互
璁╀綘鍦ㄥ嚑涔庢墍鏈塁++緙栬瘧鍣ㄤ腑閮藉彲浠ヨ繖鏍鋒柟渚跨殑浣跨敤__uuidof銆傝繖閲屾病鏈夎鏄墍鏈夛紝鏄洜涓烘垜浠嬌鐢ㄤ簡妯℃澘鐗瑰寲鎶鏈紝鍙兘瀛樺湪涓浜涙瘮杈?#8220;鍙よ?#8221;鐨?
C++緙栬瘧鍣紝涓嶆敮鎸佽鐗規с?
銆銆涔熻浣犲凡緇忚揩涓嶅強寰呬簡銆傚ソ錛岃鎴戜滑鏉ョ湅鐪嬶細
#include <string>
#include <cassert>
inline STDMETHODIMP_(GUID) GUIDFromString(LPOLESTR lpsz)
{
HRESULT hr;
GUID guid;
if (lpsz[0]=='{')
{
hr=CLSIDFromString(lpsz,&guid);
}
else
{
std::basic_string<OLECHAR> strGuid;
strGuid.append(1,'{');
strGuid.append(lpsz);
strGuid.append(1,'}');
hr = CLSIDFromString((LPOLESTR)strGuid.c_str(),&guid);
}
assert(hr==S_OK);
return guid;
}
template <class Class>
struct _UuidTraits {
};
#define _DEFINE_UUID(Class,uuid) \
template <> \
struct _UuidTraits<Class>{ \
static const GUID& Guid(){ \
static GUID guid=GUIDFromString(L## uuid); \
return guid; \
} \
}
#define __uuidof(Class) _UuidTraits<Class>::Guid()
#define DEFINE_CLSID(Class,guid) \
class Class; \
_DEFINE_UUID(Class,guid)
#define DEFINE_IID(Interface,iid) \
struct Interface; \
_DEFINE_UUID(Interface,iid)
銆銆榪欐牱涓鏉ワ紝灝卞凡緇忔ā鎷熷嚭涓涓猒_uuidof鍏抽敭瀛椼傛垜浠彲浠ュ緢鏂逛究榪涜uuid鐨勫畾涔夈備婦渚嬪涓嬶細
void test()
{
CLSID clsid=__uuidof(Class);
IID iid=__uuidof(Interface);
...
}銆銆
銆銆鍦╒C++涓紝涓轟簡涓庡叾浠栫紪璇戝櫒浠ョ浉鍚岀殑鏂瑰紡鏉ヨ繘琛寀uid鐨勫畾涔夛紝鎴戜滑涓嶇洿鎺ヤ嬌鐢╛_declspec(uuid)錛岃屾槸涔熷畾涔塂EFINE_CLSID, DEFINE_IID瀹忥細
#define DEFINE_CLSID(Class,clsid) \
class __declspec(uuid(clsid)) Class
#define DEFINE_IID(Interface,iid) \
struct __declspec(uuid(iid)) Interface
銆銆榪欐牱涓鏉ワ紝鎴戜滑宸茬粡鍦ㄦ墍鏈夊寘鍚玍C++鍦ㄥ唴鐨勬敮鎸佹ā鏉跨壒鍖栨妧鏈殑緙栬瘧鍣ㄤ腑錛屾彁渚涗簡__uuidof鍏抽敭瀛椼傞氳繃瀹冨彲浠ヨ繘涓姝ョ畝鍖栦綘鍦–++璇█涓疄鐜癈OM緇勪歡鐨勪唬浠楓?
銆銆闄勬敞錛氬叧浜庢湰鏂囦嬌鐢ㄧ殑C++妯℃澘鐨勭壒鍖栨妧鏈紝璇︾粏璇峰弬闃匔++鏂囨硶鏂歸潰鐨勪功綾嶏紝渚嬪銆奀++ Primer銆嬨傚叾瀹炶繖涓妧宸у湪C++鏍囧噯搴撯斺擲TL涓湁涓涓笓闂ㄧ殑鍚嶅瓧錛歵raits錛堣悆鍙栵級錛屼綘鍙互鍦ㄥ緢澶氫粙緇峉TL鐨勪功綾嶄腑瑙佸埌鐩稿叧鐨勪粙緇嶃?
銆銆杞敞錛氬洜涓鴻嚜宸變互鍚庡啓鐨勬枃绔犻渶瑕佺敤鍒扮被浼肩殑鎶宸э紝鍥犳鍏堟惉榪囨潵鏀捐繖銆?/p>
銆銆涓嶈繃寰堝浜哄茍涓嶇煡閬擄紝榪欏叾瀹炴槸涓涓紪璇戝櫒鎵╁睍鍏抽敭瀛楋紝鎻愪緵浜嗘鍏抽敭瀛楃殑浠匳C涓瀹跺埆鏃犲畠搴椼傚垢榪愮殑鏄紝寮哄ぇ鐨凜++璁╂垜浠兘澶熻交鏄撲豢鐪熷嚭榪欎釜鍏抽敭瀛楃殑澶ч儴鍒嗗姛鑳姐?
銆銆緗戜笂鑳藉鎵懼埌涓縐嶄豢鐪熺殑鏂規硶錛岃璁稿紡浼?銆婁豢鐪烿C++鎻愪緵鐨勫叧閿瓧__uuidof銆?/a>銆傝鏂規硶鐨勫疄鐜版槸錛氱壒鍖栨ā鏉跨被鐨勬垚鍛樺嚱鏁幫紝鐒跺悗榪愯鏃惰皟鐢ㄥ嚱鏁版牴鎹甎UID瀛楃涓蹭駭鐢熷嚭UUID錛岀敱浜庢槸鐢熸垚浜庤繍琛屾椂錛屾墍浠ュ畠鏃犲彲閬垮厤鍦版湁涓や釜緙虹偣錛?
銆銆閭d簺鏁村ぉ嫻佺潃鍙f按榪芥眰鏁堢巼鐨凜++紼嬪簭鍛樹滑錛屾槸涓嶈兘蹇嶅彈浠諱綍涓嶅繀瑕佺殑榪愯鏃舵秷鑰楃殑銆傚浜庣浜岀偣錛孷C鐨勫叧閿瓧__uuidof鍙栧嚭鏉ョ殑UUID 鏄兘澶熶綔涓洪潪綾誨瀷妯℃澘鍙傛暟浼犻掔殑錛孉TL涓氨澶ч噺鍦頒嬌鐢ㄤ簡榪欐牱鐨勫弬鏁頒紶閫掑艦寮忥紝鎵浠ョ洰鍓嶇殑榪欑瀹炵幇鍔熻兘鏈夐檺錛屼豢鐪熷害榪樹笉澶熼珮銆?
銆銆鍏跺疄鍙鑳借瀹冭兘澶熺紪璇戞湡鍐沖畾UUID鐨勫鹼紝閭d箞榪欎袱涓棶棰樺氨榪庡垉鑰岃В浜嗐傝岃繖鏄偗瀹氬彲浠ュ疄鐜扮殑錛屽茍涓斿緢綆鍗曘傛垜鏇劇粡鍦ㄨ嚜宸卞啓鐨勪竴涓狢OM搴撻噷瀹炵幇榪囪繖鏍風殑鏂規硶錛岃櫧鐒墮偅涓簱宸茬粡涓嶇煡涓㈠埌鍝噷鍘諱簡錛屼笉榪囬偅涓柟娉曡繕璁板緱銆?
銆銆瑙e喅鐨勯斿緞榪樻槸紱諱笉寮妯℃澘鐗瑰寲銆傜被鐨勬垚鍛樺寘鎷垚鍛樺嚱鏁板拰鎴愬憳鍙橀噺錛屽嚱鏁版槸榪愯鏃朵綔鐢ㄧ殑錛岀劧鑰宻tatic const鐨勬垚鍛樺彉閲忓彲浠ユ槸緙栬瘧鏈熷氨鍐沖畾銆傛墍浠ヨВ鍐崇殑鏂規硶灝卞湪鐪煎墠浜嗭細鐗瑰寲妯℃澘鐨勬垚鍛樺彉閲忋?
銆銆浠ヤ笅鏄垜鐨勫疄鐜版柟娉曘?
銆銆鍏堝畾涔変竴涓被妯℃澘錛屽畠鏈変竴涓猻tatic const ,UUID綾誨瀷鐨勬垚鍛樺彉閲忥細
template<typename T>
struct _uuid_of_impl
{
static const UUID id;
};
template<typename T>
const UUID _uuid_of_impl<T>::id=GUID_NULL;
銆銆鏈変簡榪欎釜綆鍗曠殑涓滆タ灝卞ソ鍔炰簡錛屽彧闇瑕侀拡瀵規煇涓帴鍙g壒瀹冪殑鎴愬憳鍙橀噺灝辮浜嗭紝濡傦細
template<>
const UUID _uuid_of_impl<IUnknown>::id=IID_IUnknown;
template<>
const UUID _uuid_of_impl<IDispatch>::id=IID_IDispatch;
銆銆鐒跺悗鎴戜滑灝卞彲浠ヨ繖鏍峰彇寰楁帴鍙g殑UUID錛?/p>
IID IunknownID=_uuid_of_impl<IUnknown>::id;
IID IdispatchID=_uuid_of_impl<IDispatch>::id;
銆銆浣滀負闈炵被鍨嬫ā鏉垮弬鏁頒紶閫掞細
template<const IID* t_iid>
struct __uuid_of_test
{
__uuid_of_test()
{}
void test()
{
t_iid;
}
};
__uuid_of_test<&(_uuid_of_impl<IDispatch>::id) > obj;
銆銆涓嶈繃鐜板湪榪欑瀹炵幇榪樻湁涓浜涢棶棰橈紝鐪嬩互涓嬩唬鐮侊細
IID ITypelibID=_uuid_of_impl<ITypeLib>::id;
銆銆娉ㄦ剰鎴戜滑騫舵病鏈変簨鍏堝妯℃澘__uuid_of_impl鐗瑰寲ITypeLib鐨勭増鏈備絾鏄互涓婅鍙ュ嵈鑳藉緙栬瘧閫氳繃錛屽湪榪愯鏃訛紝
__uuid_of_impl<ITypeLib>鐨勫煎皢浼氭槸閿欒鐨勫糋UID_NULL銆傝繖鏄洜涓猴紝鎴戜滑瀹氫箟妯℃澘鐨勬椂鍊欙紝鍚屾椂鍦ㄦā鏉垮瀹氫箟
浜嗘ā鏉跨殑闈欐佹垚鍛樺彉閲忓茍璧嬪間負GUID_NULL錛屾墍浠ユ病鏈夌敤鐗瑰寲鐨勬柟娉曞畾涔塙UID鐨勬帴鍙o紝閮藉皢浣跨敤GUID_NULL榪欎釜閫氱敤鍊箋傝繖褰撶劧涓嶆槸鎴戜滑鎯寵
鐨勩傛墍浠ユ垜浠兂鍦ㄦ病鏈夊畾涔塙UID鐨勬椂鍊欒緙栬瘧鍣ㄨ鍛婃垜浠紝瑕佽揪鍒拌繖鏍風殑鏁堟灉鍙渶瑕佸幓鎺変笂闈㈤偅鍙ワ細
template<typename T>
const UUID _uuid_of_impl<T>::id=GUID_NULL;
銆銆鐜板湪鍐嶈繘琛岀紪璇戯紝緙栬瘧鍣ㄤ細鍛婅瘔浣狅紝鏈変竴涓棤娉曡В鏋愮殑絎﹀彿銆傛牴鎹紪璇戝櫒鎻愪緵鐨勭浉鍏充俊鎭紝寰堝鏄撳氨鑳界‘瀹氶棶棰樻墍鍦ㄣ傝繖鏍瘋兘澶熷湪緙栬瘧鏈熸瀬澶у湴鍑忓皬瀹夊叏闅愭偅銆?
銆銆鏈鍚庡姞涓婃垜浠畾涔夌殑鍑犱釜瀹忥紝榪欐槸鏈鍚庣殑鍏ㄩ儴瀹炵幇錛?/p>
template<typename T>
struct _uuid_of_impl
{
static const UUID id;
};
#define uuid_of(x) _uuid_of_impl<x>::id
#define DEFINE_UUID(x,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
template<> \
const UUID _uuid_of_impl<x>::id={l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
銆銆鐢ㄤ互涓嬩唬鐮佹祴璇曢氳繃錛?/p>
struct ITest{};
DEFINE_UUID(ITest,0x96289151,0xf059,0x4049,0x88,0x19,0x61,0xa6,0xe9,0x79,0xc,0xf1);
template<const IID* t_iid>
struct uuid_of_test
{
uuid_of_test(){}
};
int main()
{
IID xxxxID=uuid_of(ITest);
uuid_of_test<&(uuid_of(ITest))> obj;
return 0;
}
銆銆闇瑕佹敞鎰忕殑鏄疍EFINE_UUID搴旇鍦ㄥ疄鐜版枃浠訛紙*.cpp錛?.cxx錛?#8230;…錛夊綋涓嬌鐢ㄣ傚埌榪欓噷錛屼粛鏈変竴浜涗嬌鐢ㄦ柟娉曚笌VC鐨勫叧閿?
瀛楁槸涓嶄竴鏍風殑錛屾墍浠ヤ粛娌″仛鍒頒豢鐪熷害100%銆備笉榪囨垜鐩鎬俊閫氳繃棰勫鐞嗗厓緙栫▼錛岃兘澶熺浉褰撶▼搴﹀湴閫艱繎瀹冿紝鍙槸鎴戝棰勫鐞嗗厓緙栫▼涓嶆槸寰堜簡瑙o紝鎵浠ュ氨涓嶅湪榪欓噷鐚笐
浜嗐?/p>
銆銆鍊熺敤 CCTV10銆婅蛋榪戠瀛︺嬬殑璇皵錛氶偅涔堣繖涓縐樼殑鍏抽敭鍏抽敭瀛楀埌搴曟槸浠涔堝憿錛熷畠鍙堝疄鐜頒簡浠涔堢濂囩殑鍔熻兘鍛紵甯︾潃榪欎竴榪炰覆鐨勭枒闂紝璁╂垜浠厛鏉ョ湅涓涓叿浣撶殑渚嬪瓙銆?/p>
銆銆鎴戝湪鑷繁鏇劇粡鍐欑殑涓涓狦UI妗嗘灦褰撲腑錛屼負浜嗗疄鐜版秷鎭笌澶勭悊鍑芥暟鑷姩鏄犲皠鐨勶紝灝遍渶瑕佹眰鍔╀簬榪欑鍔熻兘銆傛瘮濡傝鏈変竴涓獥鍙g被錛屽畠鍖呭惈鑻ュ共娑堟伅澶勭悊鍑芥暟鍜屼竴涓秷鎭笌澶勭悊鍑芥暟鐨勬槧灝?map錛氾紙璇鋒棤瑙嗗綋涓殑 show() 鍜?create() 鍑芥暟錛屼笌涓婚鏃犲叧錛?/p>
class Window
{
typedef UINT _Message;
typedef LRESULT (Window::*_Handler)(_Message);
map<_Message,_Handler> m_handlerMap;
public:
bool show();
bool create();
public:
LRESULT onEvent( WindowEvent<WM_CREATE> );
LRESULT onEvent( WindowEvent<WM_DESTROY> );
};
銆銆
銆銆鎴戦渶瑕佸埄鐢ㄦā鏉垮厓緙栫▼ 浠?0 鍒?WM_USER 榪涜寰幆媯嫻嬶紝媯嫻?Window
綾繪槸鍚﹀瓨鍦ㄨ娑堟伅瀵瑰簲鐨勫鐞嗗嚱鏁般傚鏋滄秷鎭搴旂殑澶勭悊鍑芥暟瀛樺湪錛岄偅涔堝氨灝嗘秷鎭笌鍑芥暟鐨勬槧灝勬斁榪?m_handlerMap 褰撲腑銆傛瘮濡傝娑堟伅
WM_CREATE錛屾垜媯嫻嬬被 Window鏄惁瀛樺湪 LRESULT onEvent( WindowEvent<WM_CREATE>
)
鎴愬憳鍑芥暟錛屽湪涓婁緥浠g爜涓槸瀛樺湪鐨勶紝浜庢槸鎴戝皢榪欐牱涓涓槧灝勬斁榪沵_handlerMap錛氾紙鐪熸瀹炵幇鐨勬椂鍊欙紝榪樿鑰冭檻鍑芥暟鐨勭被鍨嬨備笉鍚岀被鍨嬬殑鍑芥暟錛屾槸涓嶈兘鐩?
鎺ヨ榪?map 褰撲腑鐨勩備笉榪囧湪榪欓噷璇鋒棤瑙嗕緥瀛愬綋涓秹鍙婄殑鎵鏈夌被鍨嬭漿鎹紝涓庝富棰樻棤鍏籌級
pair<WM_CREATE,&Window::onEvent>
銆銆榪欐牱灝辮揪鍒頒簡娑堟伅鑷姩鏄犲皠鐨勭洰鐨勩傝屼笉鐢ㄥ儚MFC涓鏍鋒墜鍐欏畯鍘繪槧灝勩傦紙鏈鍚庨氳繃鍔姏鐨勭‘杈懼埌浜嗘垜鐨勭洰鐨勶紝鎴戠殑GUI妗嗘灦鑳藉榪涜鑷姩娑?
鎭槧灝勪簡錛岀劧鑰屽彲浠ラ瑙侊紝鐢變簬鍑犲崈涓紙0錛峎M_USER錛夊驚鐜紝緙栬瘧鏈熺殑閫熷害鍙楀埌鏋佸ぇ褰卞搷銆傛墍浠ユ渶緇堟垜榪樻槸鎶涘純浜嗚繖縐嶈嚜鍔ㄦ槧灝勫疄鐜幫紝鑰岄噰鐢ㄤ簡鏇撮珮鏁堢濂?
鐨勬柟娉曪紝榪欐槸鍚庤瘽涔熶笌鏈富棰樻棤鍏沖氨鍏堜笉鎻愶級銆?/p>
銆銆瑕佸疄鐜頒互涓婄殑鑷姩鏄犲皠鍔熻兘灝卞紩鍑轟簡榪欐牱涓涓毦棰橈細濡備綍緙栬瘧鏈熸嫻嬬被鐨勬煇鐗瑰畾鍚嶅瓧鐨勬垚鍛樻槸鍚﹀瓨鍦ㄣ?/p>
銆銆鍔熻兘涓嶈礋鏈夊績浜猴紝緇忚繃鐖北娑夋按緲誨北瓚婂箔錛屾垜緇堜簬鍦?MSDN
涓涓亸榪滆钀介噷鎵劇潃浜嗕紶璇村綋涓偅涓縐樼殑鍏抽敭瀛楋細__if_exists錛堝叾瀹炶繕鏈変竴涓?__if_not_exists錛夈侻SDN
褰撲腑榪欐牱璇存槑錛歘_if_exists
錛坃_if_not_exists錛夊厑璁鎬綘閽堝鏌愮鍙風殑瀛樺湪涓庡惁鏉′歡鎬у湴鎵ц璇彞銆備嬌鐢ㄨ娉曪細錛堟敞鎰忔嫻嬬殑鏄?#8220;瀛樺湪鎬?#8221;錛岃屼笉鏄鹼級
__if_exists ( /*浣犺媯嫻嬪瓨鍦ㄦх殑鍑芥暟鎴栧彉閲忕殑鍚嶅瓧*/ ) {
銆//鍋氫簺鏈夌敤鐨勪簨
}
// the__if_exists_statement.cpp
// compile with: /EHsc
#include <iostream>
template<typename T>
class X : public T {
public:
void Dump() {
std::cout << "In X<T>::Dump()" << std::endl;
__if_exists(T::Dump) {
T::Dump();
}
__if_not_exists(T::Dump) {
std::cout << "T::Dump does not exist" << std::endl;
}
}
};
class A {
public:
void Dump() {
std::cout << "In A::Dump()" << std::endl;
}
};
class B {};
bool g_bFlag = true;
class C {
public:
void f(int);
void f(double);
};
int main() {
X<A> x1;
X<B> x2;
x1.Dump();
x2.Dump();
__if_exists(::g_bFlag) {
std::cout << "g_bFlag = " << g_bFlag << std::endl;
}
__if_exists(C::f) {
std::cout << "C::f exists" << std::endl;
}
return 0;
}
銆銆浠ヤ笂浠g爜鐨勮緭鍑哄涓嬶細錛堟湭嫻嬭瘯錛屾杈撳嚭涓篗SDN鐨勮鏄庢枃妗e綋涓殑錛?/p>
In X<T>::Dump()
In A::Dump()
In X<T>::Dump()
T::Dump does not exist
g_bFlag = 1
C::f exists
銆銆澶ф寰堝皯浜鴻榪囪繖涓叧閿瓧鍚с傝櫧鐒跺畠浠殑鍔熻兘涓庢垜鐨勯渶姹傛槸濡傛鐨勬帴榪戯紝浣嗘槸闈㈠濡傛寮烘喚鐨勫叧閿瓧錛屾垜榪樻槸鍙兘鎽囧ご鍙規伅銆傛垜浼ゅ績鍦板湪鏂囨。
閲岀湅鍒拌鏄庯紝__if_exists錛坃_if_not_exists錛夊叧閿瓧鐢ㄤ簬鍑芥暟鐨勬椂鍊欙紝鍙兘鏍規嵁鍑芥暟鍚嶅瓧榪涜媯嫻嬶紝鑰屼細蹇界暐瀵瑰弬鏁板垪琛ㄧ殑媯嫻嬶紝鍥?
姝ゆ病鏈夊閲嶈澆鍑芥暟鐨勫垎杈ㄨ兘鍔涳紝鑰屾鏄垜闇瑕佺殑銆傛瘮濡傜被 Window 鏈変竴涓嚱鏁幫細
LRESULT Window::onEvent( WindowEvent<WM_DESTROY> )
{
//鍋氫簺鏈夌敤鐨勪簨
}
銆銆鎴戠敤浠ヤ笅浠g爜鏉ユ嫻?WM_CREATE 娑堟伅鏄惁瀛樺湪澶勭悊鍑芥暟錛?/p>
__if_exists(Window::onEvent)
銆銆{
//娣誨姞娑堟伅鏄犲皠
}
銆銆鍗充嬌 Window 綾誨綋涓笉瀛樺湪 LRESULT onEvent (
WindowEvent<WM_CREATE> )錛屼互涓婃祴璇曚篃鑳介氳繃銆傝繖鏄洜涓?__if_exists
鍏抽敭瀛楁槸涓嶇鍑芥暟閲嶈澆鐨勶紝濡傛灉瀛樺湪涓涓?onEvent 錛岄偅涔堟墍鏈夌殑媯嫻嬮兘鑳介氳繃銆傝繖涓嶆槸鎴戞兂瑕佺殑銆傛垜闇瑕佹瘮 __if_exists
鏇村己鎲劇殑媯嫻嬪姛鑳斤紝寮烘喚鍒拌兘澶熼拡瀵逛笉鍚屽弬鏁板垪琛ㄧ殑鍚屽悕鍑芥暟錛堥噸杞藉嚱鏁幫級鍋氬嚭姝g‘鐨勫瓨鍦ㄦф祴璇曘?/p>
銆銆浜庢槸鎴戠戶緇炕灞辮秺宀湴瀵繪壘錛屼粠 CSDN 鍒?MSDN錛屼粠 SourceForge 鍒?CodeProject銆傝鐩鎬俊閭e彞鑰佽瘽錛?#8220;鏈夊績浜哄ぉ涓嶈礋”銆傛渶鍚庢垜鍦?CodeProject 涓婇潰鐪嬪埌涓綃囪鎴戦啀閱愮亴欏剁殑鏂囩珷錛?/p>
銆銆Interface Detection by Alexandre Courpron
銆銆榪欑瘒鏂囩珷浠庡師鐞嗗埌瀹炵幇錛屽緢璇︾粏鍦拌鏄庡湴涓縐嶇紪璇戞湡媯嫻嬫妧鏈紝鍏堣鏄庝竴涓嬶紝鐢變簬VC7.1鏁板崈涓猙ug褰撲腑鐨勪竴涓紝浠ヤ笅鎶鏈笉鑳藉湪VC++7.1鎴栨洿浣庣増鏈笂浣跨敤銆傚叿浣撶殑瀹炵幇鍦ㄩ偅綃囨枃绔犲綋涓寰楀緢璇﹀敖浜嗭紝榪樻槸鍦ㄨ繖鍎胯禈榪頒竴涓嬨?/p>
銆銆Alexandre Courpron鐨勫疄鐜版柟寮忓熀浜嶤++鐨勮繖鏍蜂竴涓鍒欙細Substitution Failure Is Not An Error 錛堢畝縐癝FINAE錛夈傚畠鐨勫惈涔夋垜涔熺悊瑙e緱姣旇緝鍚硦錛屼笉榪囧畠浣滅敤浜庨噸杞藉嚱鏁扮殑鏃跺欙紝鍙互榪欐牱鐞嗚В錛氬浜庝竴涓嚱鏁拌皟鐢紝鍦ㄥ尮閰嶅嚱鏁扮殑榪囩▼褰撲腑錛屽鏋滄渶緇堣兘澶? 鏈変竴涓嚱鏁板尮閰嶆垚鍔燂紝閭d箞瀵瑰叾浣欏嚱鏁扮殑鍖歸厤濡傛灉澶辮觸錛岀紪璇戝櫒涔熶笉浼氳涓洪敊璇傚惉璧鋒潵鏈変簺楹葷儲錛岀湅Alexandre Courpron緇欏嚭鐨勪緥瀛愶細
struct Test
{
typedef int Type;
};
template < typename T >
void f(typename T::Type) {} // definition #1
template<typename T>
void f(T){} // definition #2
f<Test>(10); //call #1
f<int>(10); //call #2
銆銆
銆銆瀵逛簬 call#1 緙栬瘧鍣ㄧ洿鎺ュ尮閰?definition#1 鎴愬姛銆傚浜?call#2錛岀紪璇戝櫒鍏堢敤 definition#1 鍖歸厤 濡備笅錛?/p>
void f( typename int::Type ) {}
銆銆榪欐樉鐒舵槸涓嶆紜殑銆備笉榪囩紪璇戝櫒騫舵病鏈夌紪璇戝け璐ユ姤鍛婇敊璇紝鍥犱負涓嬮潰鐨?definition#2 鍖歸厤鎴愬姛錛屾牴鎹?SFINAE鐨?瑙勫垯錛岀紪璇戝櫒鏈夋潈淇濇寔娌夐粯 銆?/p>
銆銆铏界劧鏄釜灝忓皬鐨勮鍒欙紝鍦ㄥ鉤鏃跺嚑涔庝笉浼氭敞鎰忓畠銆傜劧鑰屽湪榪欏効錛屾垜浠嵈鍙互鍒╃敤瀹冨疄鐜扮紪璇戞湡媯嫻嬬殑寮哄ぇ鍔熻兘浜嗭紝涓涓渶綆鍗曠殑紺轟緥錛?/p>
#include <iostream>
using namespace std;
//
struct TestClass
{
void testFun();
};
struct Exists { char x;};
struct NotExists { char x[2]; };
template <void (TestClass::*)()>
struct Param ;
template <class T>
Exists isExists( Param<&T::testFun>* );
template <class T>
NotExists isExists( ... );
//
int main()
{
cout<<sizeof(isExists<TestClass>(0))<<endl;
}
銆銆涓婇潰鐨勪唬鐮佷細杈撳嚭 錛戙傝鏄庝竴涓嬫嫻嬬殑榪囩▼錛?/p>
銆銆濡傛灉鏄垜浠妸 TestClass 鐨勫畾涔変慨鏀逛負錛氾紙浠呮妸鍑芥暟鐨勫弬鏁扮被鍨嬫敼涓?int 錛?/p>
struct TestClass
{
void testFun(int);
};
銆銆榪欎竴嬈′唬鐮佷細杈撳嚭 錛掋傚洜涓哄湪絎紦姝ョ殑鏃跺欙紝鐢變簬 TestClass 娌℃湁綾誨瀷涓?void
(TestClass::*)()錛屼笖鍚嶄負 testFun 鐨勫嚱鏁幫紝鎵浠ュ疄渚嬪寲 Param
浼氬け璐ワ紝鍥犳鍖歸厤絎竴涓嚱鏁板け璐ャ傜劧鍚庣紪璇戝櫒鍘誨尮閰嶇浜屼釜鍑芥暟銆傚洜涓哄叾鍙傛暟綾誨瀷鏄換鎰忕殑錛岃嚜鐒朵細鍖歸厤鎴愬姛銆傜粨鏋滀細杈撳嚭 2銆?/p>
銆銆褰撶劧榪欏彧鏄釜鏈綆鍗曠殑紺轟緥錛岄氳繃妯℃澘鍖呰綾匯傚彲浠ュ疄鐜版洿鐏墊椿鏇村己澶х殑鍔熻兘銆傛瘮濡傚洖鍒伴偅涓嚜鍔ㄦ秷鎭槧灝勭殑渚嬪瓙錛岀敤浠ヤ笅浠g爜灝辮兘澶熷疄鐜頒簡錛?/p>
//c++std
#include <iostream>
using namespace std;
//windows
#include <windows.h>
//detector
template<typename TWindow,UINT t_msg>
struct MessageHandlerDetector
{
typedef WindowEvent<t_msg> _Event;
struct Exists {char x;};
struct NotExists {char x[2];};
template<LRESULT (TWindow::*)(_Event)>
struct Param;
template<typename T>
static Exists detect( Param<&T::onEvent>* );
template<typename T>
static NotExists detect( ... );
public:
enum{isExists=sizeof(detect<TWindow>(0))==sizeof(Exists)};
};
//test classes
struct Window
{
LRESULT onEvent( WindowEvent<WM_CREATE> );
};
struct Button
{
LRESULT onEvent( WindowEvent<WM_DESTROY> );
};
//main
int main()
{
cout<<MessageHandlerDetector<Window,WM_CREATE>::isExists<<endl;
cout<<MessageHandlerDetector<Window,WM_DESTROY>::isExists<<endl;
cout<<MessageHandlerDetector<Button,WM_CREATE>::isExists<<endl;
cout<<MessageHandlerDetector<Button,WM_DESTROY>::isExists<<endl;
return 0;
}
銆銆浠ヤ笂浠g爜浼氳緭鍑猴細
1
0
0
1
銆銆浠ヤ笂鐨勭ず渚嬩唬鐮佸啀鍔犱笂妯℃澘鍏冪紪紼嬶紝鍙互寰堣交鏄撳湴瀹炵幇娑堟伅鐨勮嚜鍔ㄦ槧灝勶紝鍏蜂綋瀹炵幇榪欎釜宸蹭笉鍦ㄦ湰璐寸殑璁ㄨ鑼冨洿騫朵笖榪欑鑷姩鏄犲皠鐨勫疄鐜幫紝澶繃澶嶆潅錛屽湪緙栬瘧鏈熸病鏈夋晥鐜囷紝涓斾笉澶熺伒媧匯備笉榪囧湪娑堟伅鏄犲皠鏈哄埗涓婃潵璇達紝宸茬О寰椾笂鏄竴縐嶉潻鍛芥х殑灝濊瘯銆?/p>
銆銆鍦ㄨ瀹屼簡榪欐墍鏈変竴鍒囦箣鍚庯紝鍐嶅憡璇変綘涓涓垜鏈榪戞墠鐭ラ亾鐨勭瀵嗭紙涓嶅噯絎戞垜瀛ら檵瀵¢椈錛夛細鍏跺疄 boost 搴撳綋涓凡鏈夌浉鍏沖姛鑳界殑 MPL 宸ュ叿瀛樺湪錛屽彨鍋?has_xxx銆?/p>
銆銆婧愭枃浠訛細<boost\mpl\has_xxx.hpp>
銆銆鏂囨。錛?a target="_blank">http://www.boost.org/doc/libs/1_35_0/libs/mpl/doc/refmanual/has-xxx-trait-def.html銆?/p>