Is it possible to create a template accepting types which implement certain interface?
For example, I want to say to template user: you can store anything in my container as long as it implements Init()
and Destroy()
methods.
Thanks
A limited subset of the (intended, but unfortunately cut) C++0x functionality of concepts is provided by the Boost Concept Check library. You can harness it by creating a concept check class for your required interface.
Firstly, if you require the existence of Init and Destroy, it means the template code uses them somewhere. This means, their existance is already checked by the compiler, as the template won't compile if the type doesn't have those methods.
However, if you want to check for them, then one way might be to use their addresses in some compile-time context, e.g
template <class T>
class X
{
private:
template <unsigned N>
struct Number {};
Number<sizeof(&T::Init) + sizeof(&T::Destroy)> must_define_init_and_destroy();
};
struct A
{
bool Init();
void Destroy();
};
struct B {};
int main()
{
X<A>();
X<B>();
}
With Comeau the output is:
"ComeauTest.c", line 7: error: class "B" has no member "Init"
Number<sizeof(&T::Init) + sizeof(&T::Destroy)> must_define_init_and_destroy();
^
detected during instantiation of class "X<T> [with T=B]" at line 21
"ComeauTest.c", line 7: error: class "B" has no member "Destroy"
Number<sizeof(&T::Init) + sizeof(&T::Destroy)> must_define_init_and_destroy();
^
detected during instantiation of class "X<T> [with T=B]" at line 21
However, this breaks down if either of the required methods is overloaded, and naturally this still doesn't test whether these methods have a suitable prototype.
E.g perhaps you expect bool Init(int, int). You could use a static_cast to check for exact signature, but again this might place unnecessary restrictions on the type. For example, so what if some class has bool Init(long, long) instead)?
One way or another, this effort seems necessary only to make the error messages more obvious. However, I very much doubt that any message that you'd get otherwise without any concepts checks (a la "no suitable method Init to call with T = X when used here") is that bad.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With