Re: Guarantee initialized legacy variables
On May 31, 9:58 am, s...@crocker.com wrote:
Approach:
I have a template: Initialised<T>, and a set of partial
specializations of Initialised<T>.
You may want to know that such a thing already exists in boost, called
value_initialized.
T must be a PODT, or a sturct of PODTs, or array of PODTs. If T were
not a plain old data type, then it would have its own ctor, and
wouldn't need a templated wrapper to ensure its proper initialization.
An array of POD types is already a POD type.
And a structure of POD types is already a POD type too.
There is no rationale though for preventing usage of your template
with non-POD types.
Problems:
P(1): I have a possible solution, but would like community feedback on
a technique for allowing an Initialised<T*> to be assigned NULL (I
certainly wish to allow this, its just a matter of what technique is
best).
Pointers are PODs, there is no need to specialize them.
P(2): I am unable to discern how to partially specialize
Initialised<T> for T being an array of PODTs.
There is no need to specialize for arrays either.
P(3): I am unable to discern how to partially specialize
Initialised<T> for T being a struct of PODTs.
No need either.
Lets start with the basic definition of Initialised<T>:
template <typename T>
struct Initialised
{
// default valued construction
Initialised() : m_value(0) { }
replace m_value(0) by m_value() and it works as expected.
// implicit valued construction (auto-conversion)
template <typename U> Initialised(const U & rhs) : m_value(rhs) { }
// assignment
template <typename U> T & operator = (const U & rhs) { if
((void*)&m_value != (void*)&rhs) m_value = rhs; return *this; }
The test is not needed.
No need to optimize for a case that never happens.
Here is the partial specialization for raw pointers:
template <typename T>
struct Initialised<T*>
{
// default valued construction
Initialised() : m_value(NULL) { }
// valued construction (auto-conversion)
template <typename U> Initialised(const U * rhs) : m_value(rhs) { }
// assignment
template <typename U> T* & operator = (U * rhs) { if (m_value != rhs)
m_value = rhs; return *this; }
template <typename U> T* & operator = (const U * rhs) { if (m_value !
= rhs) m_value = rhs; return *this; }
There is no need for the second assignment operator.
The first one works just as well, since U can be a const type too.
// pointer semantics
const T * operator -> () const { return m_value; }
T * operator -> () { return m_value; }
const T & operator * () const { return *m_value; }
T & operator * () { return *m_value; }
Oh, so that's why you wanted to specialize it for pointers.
You might as well just overload operator-> in the general case
(operator* shouldn't be needed, thanks to the implicit conversion
operators).
Which brings me to question / problem P(2) - is there a syntax that
will allow me to do a partial specialization for an array of T?
There is, of course, but it's not needed at all.
I have tried:
template <typename T, size_t count>
struct Initialised<T(&)[count]>
T(&)[count] is a reference to an array, not an array.
Try with T[count].
Thanks for any feedback you may have to offer.
You just need this:
template<class T>
class Initialized
{
public:
Initialized() : x()
{
}
template<typename U>
Initialized(const U& u) : x(u)
{
}
operator T&()
{
return x;
}
operator const T&() const
{
return x;
}
T& operator->()
{
return x;
}
const T& operator->() const
{
return x;
}
private:
T x;
};
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]