问题
This is a follow up to Why aren't fields from constant POD object constants themselves?
A header from a library declares class GUIDs like
static const GUID CLSID_EH264VD =
{ 0x96b9d0ed, 0x8d13, 0x4171, { 0xa9, 0x83, 0xb8, 0x4d, 0x88, 0xd6, 0x27, 0xbe } };
I want to write a function that creates an object directly from the dll, without requiring the dll to be registered, so I need to map each CLSID to the dll name. Something like
Create<CLSID_EH264VD>()
which would depend on a specialization such as
template<>
struct dll<CLSID_EH264VD>
{
char const* filename = ""mc_dec_avc_ds.ax";
}
so that it's a compile time error to try to instantiate an unregistered class with an unknown dll.
The problem is that templates can't be specialized for GUIDs. The linked question says that constexpr would allow to declare the GUID in a way that allows specialization, but Visual C++ doesn't support constexpr in the latest version (2012). Any workaround?
回答1:
Per Paragraph 14.3.2/1 of the C++11 Standard:
A template-argument for a non-type, non-template template-parameter shall be one of:
— for a non-type template-parameter of integral or enumeration type, a converted constant expression (5.19) of the type of the template-parameter; or
— the name of a non-type template-parameter; or
— a constant expression (5.19) that designates the address of an object with static storage duration and external or internal linkage or a function with external or internal linkage, [...]
— [...]
This means that even though the GUID
itself cannot be used as a template argument, you can use the address of the global GUID
as an argument, and a pointer to GUID
as the corresponding non-type parameter:
template<GUID const* pGuid>
struct dll { };
template<>
struct dll<&CLSID_EH264VD>
// ^^^^^^^^^^^^^^
// This is a constant expression
{
char const* filename = ""mc_dec_avc_ds.ax";
}
// ...
dll<&CLSID_EH264VD> x;
回答2:
You may try
template<size_t B1,size_t B2,size_t B3,size_t B4,size_t B5,size_t B6,size_t B7,size_t B8,size_t B9,size_t B10>
class clsid_t{};
typedef clsid_t<0x96b9d0ed, 0x8d13, 0x4171, 0xa9, 0x83, 0xb8, 0x4d, 0x88, 0xd6, 0x27, 0xbe> CLSID_EH264VD;
template<>
struct dll<CLSID_EH264VD>
{
char const* static name(){return "mc_dec_avc_ds.ax";};
}
来源:https://stackoverflow.com/questions/15410833/specialize-a-template-for-a-guid-value