Domanda

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?

È stato utile?

Soluzione

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;

Altri suggerimenti

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";};
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top