Playing with templates

Hi,

Is there a way to limit a template to a supported type list ?
Look at this example below. I have 4 functions that look similar but only 4 data types should be supported.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
LONG HlpRegSetValueDword(HKEY PredefKey, PCWSTR pSubKey, PCWSTR pValName, const int *pValData)
{
	return RegSetKeyValueW(PredefKey, pSubKey, pValName, REG_DWORD, pValData, sizeof(*pValData));
}

LONG HlpRegSetValueDword(HKEY PredefKey, PCWSTR pSubKey, PCWSTR pValName, const unsigned int *pValData)
{
	return RegSetKeyValueW(PredefKey, pSubKey, pValName, REG_DWORD, pValData, sizeof(*pValData));
}

LONG HlpRegSetValueDword(HKEY PredefKey, PCWSTR pSubKey, PCWSTR pValName, const long *pValData)
{
	return RegSetKeyValueW(PredefKey, pSubKey, pValName, REG_DWORD, pValData, sizeof(*pValData));
}

LONG HlpRegSetValueDword(HKEY PredefKey, PCWSTR pSubKey, PCWSTR pValName, const unsigned long *pValData)
{
	return RegSetKeyValueW(PredefKey, pSubKey, pValName, REG_DWORD, pValData, sizeof(*pValData));
}


So I think about a simple template like that...

1
2
3
4
template<typename Type> LONG HlpRegSetValueDword(HKEY PredefKey, PCWSTR pSubKey, PCWSTR pValName, const Type *pValData)
{
	return RegSetKeyValueW(PredefKey, pSubKey, pValName, REG_DWORD, pValData, sizeof(*pValData));
}


But its not preventing the use of other types that should not be used. Is there a way to limit the data types to the only 4 I need or in this case I have to overload the function 4 times ?

Thanks
How does pValData is declared in prototype? Will it lead to error if we pass another type?

Why not allow passing of short/long long and unsigned counterparts?
 
Why not allow passing of short/long long and unsigned counterparts?


Because these functions only deals with int and long. Maybe I could add long long but I'll have to change REG_DWORD to REG_QWORD at the same time. But anyway it is sure that any other types should not be passed to this function.

http://www.cplusplus.com/reference/type_traits/

Use something like

1
2
3
4
5
6
tempate <typename T>
std::enable_if <std::is_same <typename std::make_signed <T> ::type, LONG> ::value, LONG> ::type
HlpRegSetValueDword(HKEY PredefKey, PCWSTR pSubKey, PCWSTR pValName, T *pValData)
{
	return RegSetKeyValueW(PredefKey, pSubKey, pValName, REG_DWORD, pValData, sizeof(*pValData));
}

I may have missed or added a typename in there somewhere...

Hope this helps.
You want to pass only integral types with size equal to DWORD size.

Use SFINAE:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <type_traits>
#include <windows.h>

template<typename T>
typename std::enable_if<std::is_integral<T>::value && sizeof(T) == sizeof(DWORD),
LONG>::type foo(const T*)
{}

int main()
{
    int* x;
    foo(x); //Works
    unsigned long* l;
    foo(l); //Works
    float f;
    foo (f); //Does not work, f is not integral
    long long* d;
    foo(d); //Does not work, size mismatch
    short* s;
    foo(s); //Does not work, size mismatch
}

Thank you guys !!!

I need to look at <type_traits>. Usefull stuff in there.

;-)

Registered users can post here. Sign in or register to post.