User forums > Using Code::Blocks
mingw32-g++ is special to template parameter type convert ?
(1/1)
leeya:
Handles.h has been defined:
#ifndef HANDLES_H
#define HANDLES_H
namespace Win {
template<class NativeHandle, NativeHandle NullHandle = 0>
class Handle
{
public:
typedef NativeHandle Type;
Handle (NativeHandle h = NullHandle) : _native (h) {}
bool IsNull () const throw () { return _native == NullHandle; }
NativeHandle ToNative () const { return _native; }
void Reset (NativeHandle h = NullHandle) { _native = h;}
bool operator== (Handle h) const { return _native == h.ToNative (); }
bool operator!= (Handle h) const { return _native != h.ToNative (); }
static NativeHandle NullValue () throw () { return NullHandle; }
protected:
NativeHandle H () const { return _native; }
NativeHandle & BaseHRef () { return _native; }
protected:
NativeHandle _native;
};
}
#endif // HANDLES_H
Instance.h has been defined:
#ifndef INSTANCE_H
#define INSTANCE_H
#include <Win/Handles.h>
namespace Win
{
class Instance: public Win::Handle<HINSTANCE> {
public:
Instance (HINSTANCE h = 0) : Win::Handle<HINSTANCE> (h) {}
};
}
#endif // INSTANCE_H
After building my project, I get error message of type convert:
D:\CodeWorld\RSWL2GCC\Win\Instance.h:9: error: could not convert template argument `0' to `HINSTANCE__*'
D:\CodeWorld\RSWL2GCC\Win\Instance.h:11: error: could not convert template argument `0' to `HINSTANCE__*'
:: === Build finished: 2 errors, 0 warnings ===
It was successful for VS2003.net, why failed in MingW ?
TDragon:
Try adding a static_cast to the template definition.
Nope, that doesn't work either. Thinking about C++ templates...
Final answer:
I'm stumped as to why your method doesn't work, but with some further thought I think it's also not the most correct way to do it. With your method, if you have a handle type where 0 isn't the correct null value, you would need to specify the appropriate null value every time you instantiate a handle of that type.
My solution: template specialization. Observe. (And please pardon the reformatting. I find it easier to think in my own coding style.)
--- Code: ---// This templated function handles creating appropriate null values for
// handles. Obviously. The default action is to assume that 0 makes an
// appropriate null.
template< class NativeHandle >
NativeHandle NullHandleFactory()
{
return 0;
}
// Here is your handle class, pretty much unchanged except that we now
// call NullHandleFactory everywhere.
template< class NativeHandle >
class Handle
{
public:
typedef NativeHandle Type;
Handle(NativeHandle h = NullHandleFactory< NativeHandle >())
: _native (h)
{
}
bool IsNull() const throw()
{
return _native == NullHandleFactory< NativeHandle >();
}
NativeHandle ToNative() const { return _native; }
void Reset (NativeHandle h = NullHandleFactory< NativeHandle >())
{
_native = h;
}
bool operator == (Handle h) const
{
return _native == h.ToNative();
}
bool operator != (Handle h) const
{
return _native != h.ToNative ();
}
static NativeHandle NullValue() throw()
{
return NullHandleFactory< NativeHandle >();
}
protected:
NativeHandle H() const { return _native; }
NativeHandle& BaseHRef() { return _native; }
protected:
NativeHandle _native;
};
// Here is your regular old HINSTANCE handle. The unspecialized
// NullHandleFactory is appropriate here, since HINSTANCE's are pointers
// and 0 is a good pointer value.
class Instance: public Handle< HINSTANCE >
{
public:
Instance(HINSTANCE h = 0)
: Handle< HINSTANCE >(h)
{
}
};
// But here's a type that is NOT implicitly convertible from 0.
struct NoZerosAllowed
{
};
// So what do we do? We specialize the NullHandleFactory template function
// for this specific type to return something appropriate.
template<>
NoZerosAllowed NullHandleFactory()
{
return NoZerosAllowed();
}
// Now our FunkyHandle class can treat NoZerosAllowed handles just like
// other handles
class FunkyHandle : public Handle< NoZerosAllowed >
{
public:
// If we hadn't specialized NullHandleFactory, an error would be thrown here
// because we're using Handle's default constructor, which calls
// NullHandleFactory
FunkyHandle()
{
}
};
--- End code ---
leeya:
:D
Thanks for your wonderful solution~~~ I can benifit from your solution.
Navigation
[0] Message Index
Go to full version