繼承根據崗位How can I define an UUID for a class, and use __uuidof, in the same way for g++ and Visual C++?雖然我不能在該職位成功編譯代碼的所有類的工作,但這個想法是好的,繼後想法在它提到的,並且其可被編譯和運行以及給出一個示例代碼下GCC解決__uuidof
#include <iostream>
#include <memory.h>
#include <assert.h>
using namespace std;
#define nybble_from_hex(c) ((c>='0'&&c<='9')?(c-'0'):((c>='a'&&c<='f')?(c-'a' + 10):((c>='A'&&c<='F')?(c-'A' + 10):0)))
#define byte_from_hex(c1, c2) ((nybble_from_hex(c1)<<4)|nybble_from_hex(c2))
typedef struct _GUID {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[ 8 ];
} GUID;
static GUID GUID_NULL = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0 ,0}};
#ifndef _REFGUID_DEFINED
#define _REFGUID_DEFINED
#ifdef __cplusplus
#define REFGUID const GUID &
#else
#define REFGUID const GUID * __MIDL_CONST
#endif
#endif
__inline int IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
{
return !memcmp(&rguid1, &rguid2, sizeof(GUID));
}
#ifdef __cplusplus
__inline bool operator==(REFGUID guidOne, REFGUID guidOther)
{
return !!IsEqualGUID(guidOne,guidOther);
}
__inline bool operator!=(REFGUID guidOne, REFGUID guidOther)
{
return !(guidOne == guidOther);
}
#endif
struct Initializable : public GUID
{
explicit
Initializable(char const (&spec)[37])
: GUID()
{
for (int i = 0; i < 8; ++i)
{
Data1 = (Data1 << 4) | nybble_from_hex(spec[i]);
}
assert(spec[8] == '-');
for (int i = 9; i < 13; ++i)
{
Data2 = (Data2 << 4) | nybble_from_hex(spec[i]);
}
assert(spec[13] == '-');
for (int i = 14; i < 18; ++i)
{
Data3 = (Data3 << 4) | nybble_from_hex(spec[i]);
}
assert(spec[18] == '-');
for (int i = 19; i < 23; i += 2)
{
Data4[(i - 19)/2] = (nybble_from_hex(spec[i])<<4) | nybble_from_hex(spec[i+1]);
}
assert(spec[23] == '-');
for (int i = 24; i < 36; i += 2)
{
Data4[2 + (i - 24)/2] = (nybble_from_hex(spec[i]) << 4) | nybble_from_hex(spec[i + 1]);
}
}
};
template<class T>
inline
auto __my_uuidof()
-> GUID const &
{
return GUID_NULL;
}
#define CPPX_GNUC_UUID_FOR(name, spec) \
template<> \
inline \
auto __my_uuidof<name>() \
-> GUID const& \
{ \
using ::operator"" _uuid; \
static GUID the_uuid = speC## _uuid; \
\
return the_uuid; \
} \
\
template<> \
inline \
auto __my_uuidof<name*>() \
-> GUID const& \
{ return __my_uuidof<name>(); } \
\
static_assert(true, "")
auto operator"" _uuid(char const* const s, size_t const size)
-> GUID
{
return Initializable(reinterpret_cast<char const (&)[37]>(*s));
}
#define CPPX_UUID_FOR CPPX_GNUC_UUID_FOR
#define __uuid(T) __my_uuidof<T>()
struct Foo {};
CPPX_UUID_FOR(Foo, "dbe41a75-d5da-402a-aff7-cd347877ec00");
Foo foo;
template <class T>
void QueryInterface(T** p)
{
if (p == NULL)
return;
GUID guid = "dbe41a75-d5da-402a-aff7-cd347877ec00"_uuid;
if (__uuid(T) == guid)
{
*p = &foo;
}
else
{
*p = NULL;
}
return;
}
int main()
{
Foo* p = NULL;
QueryInterface(&p);
cout << "p: " << p << ", &foo: " << &foo << endl;
return 0;
}
保存它uuidtest.cpp,我使用的克++ - 7編譯它成功(其他具有C++ 11/14支持的gcc也可以很好地工作),並且運行良好:
g++-7 uuidtest.cpp -o uuidtest
./uuidtest
p: 0x6021c0, &foo: 0x6021c0
你看過['typeid'](http://en.cppreference.com/w/cpp/language/typeid)嗎? – nwp
typeid可以在編譯期間工作以獲得像預處理指令一樣的合併變量嗎? –
不幸的是'typeid'不會產生編譯時可用值,但它仍然可以解決您在示例中顯示的問題。 – nwp