c++ - Template function overload not called as expected -
my situation following:
i have template wrapper handles situation of values , object being nullable without having manually handle pointer or new. boils down this:
struct null_t { // dummy }; static const null_t null; template<class t> class nullable { public: nullable() : _t(new t()) {} nullable(const nullable<t>& source) : _t(source == null ? 0 : new t(*source._t)) {} nullable(const null_t& null) : _t(0) {} nullable(const t& t) : _t(new t(t)) {} ~nullable() { delete _t; } /* comparison , assignment operators */ const t& operator*() const { assert(_t != 0); return *_t; } operator t&() { assert(_t != 0); return *_t; } operator const t&() const { assert(_t != 0); return *_t; } private: t* _t; }; now comparison operators can check against null_t dummy in order see whether set null before trying retrieve value or pass function requires value , automatic conversion.
this class has served me quite time, until stumbled issue. have data class containing structs outputted file (in case xml).
so have functions these
xml_iterator add(xml_iterator parent, const char* name, const mydatastruct1& value); xml_iterator add(xml_iterator parent, const char* name, const mydatastruct2& value); which each fill xml-dom proper data. works correctly.
now, however, of these structs optional, in code declared a
nullable<mydatastruct3> someoptionaldata; and handle case, made template overload:
template<class t> xml_iterator add(xml_iterator parent, const char* name, const nullable<t>& value) { if (value != null) return add(parent, name, *value); else return parent; } in unit tests compiler, expected, preferred choose template function whereever value or structure wrapped in nullable<t>.
if use aforementioned data class (which exported in own dll), reason first time last template function should called, instead automatic conversion nullable<t> respective type t done, bypassing function meant handle case. i've said above - unit tests went 100% fine, both tests , executable calling code being built msvc 2005 in debug mode - issue can not attributed compiler differences.
update: clarify - overloaded add functions not exported , used internally within dll. in other words, external program encounters issue not include head template overloaded function.
the compiler select exact match before finds templated version pick templated "exact match" on function fits, eg, 1 uses base class of type.
implicit conversions dangerous , bite you. way including headers or namespaces using.
i following:
make constructors of nullable explicit. constructors take 1 parameter, or can called 1 (even if there more have default values).
template<class t> class nullable { public: nullable() : _t(new t()) {} explicit nullable(const nullable<t>& source) : _t(source == null ? 0 : new t(*source._t)) {} explicit nullable(const null_t& null) : _t(0) {} explicit nullable(const t& t) : _t(new t(t)) {} // rest };replace operator t& conversions named functions. use ref() non-const , cref() const.
i complete class with
- assignment operator (needed rule of 3)
- operator-> 2 overloads propagating constness.
if plan use c++0x r-value copy , assign, useful in case.
by way, know deep copy won't work base classes slice.
Comments
Post a Comment