ris
asked on
default value initializer in templatized class
I want to create a templatizable class which includes a default value for the templatized data type. The following oversimplified example will work for atomic types like int and BOOL but not for data types that are structures or classes:
template <class DataType, DataType DefaultValue>
class CMyClass
{
protected:
DataType m_Data;
public
CMyClass() {m_Data = DefaultValue;}
}; //end CMyClass
I get several errors if I try to instantiate the following:
CMyClass<CString, "default string value"> MyObject;
I found that CString is not a valid type for a template argument because structures are not allowed. MSDN (my C++ documentation) says to use a pointer instead if that is the case, but when I have tried that, I get an error like "expected constant value" because I have to instantiate it something like this:
const CString DefaultValue("default string value")
CMyClass<CString*, &DefaultValue> MyObject;
and &DefaultValue is where it expects a constant value and I can't give it one. I use CString as an example, but I want to be able to use this on custom classes as well (all of which would support operator= so that the templatized constructor code m_Data = DefaultValue would work) otherwise, there are a variety of alternative solutions I could use just for strings.
--------
I want to be able to make a similar class for arrays like this:
template <class DataType, int nNumElements, const DataType* pDefaultValue>
class CMyArrayClass
{
protected:
DataType m_arData[nNumElements];
public:
CMyClass()
{
for (int i=0; i<nNumElements; i++)
m_arData[i] = pDefaultValue[i];
}
}; //end CMyArrayClass
I have tried the above code using a char array as follows:
CMyArrayClass<char, 4, "test"> MyObject;
but I get an error that "test" is an invalid template argument (even though it is a const char*). If I use NULL instead, it works, but that doesn't help me because I want to pass in an initial value other than a non-value like NULL.
So what can I do?
template <class DataType, DataType DefaultValue>
class CMyClass
{
protected:
DataType m_Data;
public
CMyClass() {m_Data = DefaultValue;}
}; //end CMyClass
I get several errors if I try to instantiate the following:
CMyClass<CString, "default string value"> MyObject;
I found that CString is not a valid type for a template argument because structures are not allowed. MSDN (my C++ documentation) says to use a pointer instead if that is the case, but when I have tried that, I get an error like "expected constant value" because I have to instantiate it something like this:
const CString DefaultValue("default string value")
CMyClass<CString*, &DefaultValue> MyObject;
and &DefaultValue is where it expects a constant value and I can't give it one. I use CString as an example, but I want to be able to use this on custom classes as well (all of which would support operator= so that the templatized constructor code m_Data = DefaultValue would work) otherwise, there are a variety of alternative solutions I could use just for strings.
--------
I want to be able to make a similar class for arrays like this:
template <class DataType, int nNumElements, const DataType* pDefaultValue>
class CMyArrayClass
{
protected:
DataType m_arData[nNumElements];
public:
CMyClass()
{
for (int i=0; i<nNumElements; i++)
m_arData[i] = pDefaultValue[i];
}
}; //end CMyArrayClass
I have tried the above code using a char array as follows:
CMyArrayClass<char, 4, "test"> MyObject;
but I get an error that "test" is an invalid template argument (even though it is a const char*). If I use NULL instead, it works, but that doesn't help me because I want to pass in an initial value other than a non-value like NULL.
So what can I do?
>>So what can I do?
There is a way around this, but it's not a clean method. In other words, it's ugly.
I'll post an example code in a follow-up comment.
The basic idea would be to create either a singleton class, or a class with a single static function, that would return the default value.
There is a way around this, but it's not a clean method. In other words, it's ugly.
I'll post an example code in a follow-up comment.
The basic idea would be to create either a singleton class, or a class with a single static function, that would return the default value.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Correction:
Even though the previous macro I posted, compiles and runs on VC++ 6.0, it shouldn't have.
The correct syntax, is the following:
#define MAKE_DEFAULT_TEMPL_VAUE(T, V) template<> T DefaultValueTemplateClass< T>::Defaul tValue(){r eturn V;}
Even though the previous macro I posted, compiles and runs on VC++ 6.0, it shouldn't have.
The correct syntax, is the following:
#define MAKE_DEFAULT_TEMPL_VAUE(T,
ASKER
I see what you are getting at there. Thanks.
Continue.....